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

Commit 5494a93d authored by Blagovest Kolenichev's avatar Blagovest Kolenichev
Browse files

Revert "ANDROID: sched: Add support for frequency/power energy model"



This reverts commit 9001b8f1.

This is a preparation change for merging android-4.14 commit
e709f59a into msm-4.14 branch.
The reverted change is rejected in msm-4.14 branch since it
does not bring in any fixes or improvements to the energy
model. Moreover the later kernels have moved on to use
simplified energy model.

Change-Id: I0005fef09e52238070d507e93c26bc69d1e82ec9
Signed-off-by: default avatarBlagovest Kolenichev <bkolenichev@codeaurora.org>
parent e709f59a
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -237,11 +237,6 @@ Property added to the cpu node:

	Any other configuration is invalid.

- freq-energy-model
	Description: Optional. Must be declared if the energy model
	represents frequency/power values. If absent, energy model is
	by default considered as capacity/power.

===========================================================
5 - Example dts
===========================================================
+0 −2
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ extern int sched_domain_level_max;

struct capacity_state {
	unsigned long cap;	/* compute capacity */
	unsigned long frequency;/* frequency */
	unsigned long power;	/* power consumption at this compute capacity */
};

@@ -195,7 +194,6 @@ typedef const struct cpumask *(*sched_domain_mask_f)(int cpu);
typedef int (*sched_domain_flags_f)(void);
typedef
const struct sched_group_energy * const(*sched_domain_energy_f)(int cpu);
extern bool energy_aware(void);

#define SDTL_OVERLAP	0x01

+6 −170
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
 */
#define pr_fmt(fmt) "sched-energy: " fmt

#define DEBUG

#include <linux/gfp.h>
#include <linux/of.h>
#include <linux/printk.h>
@@ -26,11 +28,6 @@
#include <linux/sched/energy.h>
#include <linux/stddef.h>
#include <linux/arch_topology.h>
#include <linux/cpu.h>
#include <linux/pm_opp.h>
#include <linux/platform_device.h>

#include "sched.h"

struct sched_group_energy *sge_array[NR_CPUS][NR_SD_LEVELS];

@@ -50,8 +47,6 @@ static void free_resources(void)
		}
	}
}
static bool sge_ready;
static bool freq_energy_model;

void check_max_cap_vs_cpu_scale(int cpu, struct sched_group_energy *sge)
{
@@ -88,9 +83,6 @@ void init_sched_energy_costs(void)
			pr_warn("CPU device node has no sched-energy-costs\n");
			return;
		}
		/* Check if the energy model contains frequency/power values */
		if (of_find_property(cn, "freq-energy-model", NULL))
			freq_energy_model = true;

		for_each_possible_sd_level(sd_level) {
			cp = of_parse_phandle(cn, "sched-energy-costs", sd_level);
@@ -112,18 +104,7 @@ void init_sched_energy_costs(void)
					     GFP_NOWAIT);

			for (i = 0, val = prop->value; i < nstates; i++) {
				if (freq_energy_model) {
					/*
					 * Capacity values will be calculated later using
					 * frequency reported by OPP driver and cpu_uarch_scale
					 * values.
					 */
					cap_states[i].frequency = be32_to_cpup(val++);
					cap_states[i].cap = 0;
				} else {
					cap_states[i].frequency = 0;
				cap_states[i].cap = be32_to_cpup(val++);
				}
				cap_states[i].power = be32_to_cpup(val++);
			}

@@ -149,158 +130,13 @@ void init_sched_energy_costs(void)

			sge_array[cpu][sd_level] = sge;
		}
		if (!freq_energy_model)

		check_max_cap_vs_cpu_scale(cpu, sge_array[cpu][SD_LEVEL0]);
	}
	sge_ready = true;

	pr_info("Sched-energy-costs installed from DT\n");
	return;

out:
	free_resources();
}

static int sched_energy_probe(struct platform_device *pdev)
{
	int cpu;
	unsigned long *max_frequencies = NULL;
	int ret;

	if (!sge_ready)
		return -EPROBE_DEFER;

	if (!energy_aware() || !freq_energy_model)
		return 0;

	max_frequencies = kmalloc_array(nr_cpu_ids, sizeof(unsigned long),
					GFP_KERNEL);
	if (!max_frequencies) {
		ret = -ENOMEM;
		goto exit;
	}

	/*
	 * Find system max possible frequency and max frequencies for each
	 * CPUs.
	 */
	for_each_possible_cpu(cpu) {
		struct device *cpu_dev;
		struct dev_pm_opp *opp;

		cpu_dev = get_cpu_device(cpu);
		if (IS_ERR_OR_NULL(cpu_dev)) {
			if (!cpu_dev)
				ret = -EINVAL;
			else
				ret = PTR_ERR(cpu_dev);
			goto exit;
		}

		max_frequencies[cpu] = ULONG_MAX;

		opp = dev_pm_opp_find_freq_floor(cpu_dev,
						 &max_frequencies[cpu]);
		if (IS_ERR_OR_NULL(opp)) {
			if (!opp || PTR_ERR(opp) == -ENODEV)
				ret = -EPROBE_DEFER;
			else
				ret = PTR_ERR(opp);
			goto exit;
		}

		/* Convert HZ to KHZ */
		max_frequencies[cpu] /= 1000;
	}

	/* update capacity in energy model */
	for_each_possible_cpu(cpu) {
		unsigned long cpu_max_cap;
		struct sched_group_energy *sge_l0, *sge;
		cpu_max_cap = topology_get_cpu_scale(NULL, cpu);

		/*
		 * All the cap_states have same frequency table so use
		 * SD_LEVEL0's.
		 */
		sge_l0 = sge_array[cpu][SD_LEVEL0];
		if (sge_l0 && sge_l0->nr_cap_states > 0) {
			int i;
			int ncapstates = sge_l0->nr_cap_states;

			for (i = 0; i < ncapstates; i++) {
				int sd_level;
				unsigned long freq, cap;

				/*
				 * Energy model can contain more frequency
				 * steps than actual for multiple speedbin
				 * support. Ceil the max capacity with actual
				 * one.
				 */
				freq = min(sge_l0->cap_states[i].frequency,
					   max_frequencies[cpu]);
				cap = DIV_ROUND_UP(cpu_max_cap * freq,
						   max_frequencies[cpu]);

				for_each_possible_sd_level(sd_level) {
					sge = sge_array[cpu][sd_level];
					if (!sge)
						break;
					sge->cap_states[i].cap = cap;
				}
				dev_dbg(&pdev->dev,
					"cpu=%d freq=%ld cap=%ld power_d0=%ld\n",
					cpu, freq, sge_l0->cap_states[i].cap,
					sge_l0->cap_states[i].power);
			}

			dev_info(&pdev->dev,
				"cpu=%d [freq=%ld cap=%ld power_d0=%ld] -> [freq=%ld cap=%ld power_d0=%ld]\n",
				cpu,
				sge_l0->cap_states[0].frequency,
				sge_l0->cap_states[0].cap,
				sge_l0->cap_states[0].power,
				sge_l0->cap_states[ncapstates - 1].frequency,
				sge_l0->cap_states[ncapstates - 1].cap,
				sge_l0->cap_states[ncapstates - 1].power
				);
		}
	}

	kfree(max_frequencies);
	dev_info(&pdev->dev, "Sched-energy-costs capacity updated\n");
	return 0;

exit:
	if (ret != -EPROBE_DEFER)
		dev_err(&pdev->dev, "error=%d\n", ret);
	kfree(max_frequencies);
	return ret;
}

static struct platform_driver energy_driver = {
	.driver = {
		.name = "sched-energy",
	},
	.probe = sched_energy_probe,
};

static struct platform_device energy_device = {
	.name = "sched-energy",
};

static int __init sched_energy_init(void)
{
	int ret;

	ret = platform_device_register(&energy_device);
	if (ret)
		pr_err("%s device_register failed:%d\n", __func__, ret);
	ret = platform_driver_register(&energy_driver);
	if (ret) {
		pr_err("%s driver_register failed:%d\n", __func__, ret);
		platform_device_unregister(&energy_device);
	}
	return ret;
}
subsys_initcall(sched_energy_init);
+1 −1
Original line number Diff line number Diff line
@@ -5688,7 +5688,7 @@ unsigned long capacity_curr_of(int cpu)
	return cap_scale(max_cap, scale_freq);
}

inline bool energy_aware(void)
static inline bool energy_aware(void)
{
	return sched_feat(ENERGY_AWARE);
}