aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Harkin <ryan.harkin@linaro.org>2017-07-27 09:49:09 +0100
committerRyan Harkin <ryan.harkin@linaro.org>2017-07-27 09:49:09 +0100
commitf39188fb718d2ec1272e5174a69a40f3c05c1cd2 (patch)
tree7062cdb9e2461adc727c29968c50fe3c6c4a50bf
parent79358bc12cc31657e429f0147efa922a013e3f2f (diff)
parent7278341e47b6c74208b1d51f30894c09d7132b15 (diff)
Merge branch '4.4-armlt-ipa' into 4.4-armlt
-rw-r--r--Documentation/devicetree/bindings/arm/cpus.txt17
-rw-r--r--drivers/cpufreq/Kconfig.arm2
-rw-r--r--drivers/cpufreq/arm_big_little.c41
-rw-r--r--linaro/configs/vexpress64.conf9
4 files changed, 69 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 3a07a87fef20..6aca64f289b6 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -242,6 +242,23 @@ nodes to be present and contain the properties described below.
Definition: Specifies the syscon node controlling the cpu core
power domains.
+ - dynamic-power-coefficient
+ Usage: optional
+ Value type: <prop-encoded-array>
+ Definition: A u32 value that represents the running time dynamic
+ power coefficient in units of mW/MHz/uVolt^2. The
+ coefficient can either be calculated from power
+ measurements or derived by analysis.
+
+ The dynamic power consumption of the CPU is
+ proportional to the square of the Voltage (V) and
+ the clock frequency (f). The coefficient is used to
+ calculate the dynamic power as below -
+
+ Pdyn = dynamic-power-coefficient * V^2 * f
+
+ where voltage is in uV, frequency is in MHz.
+
Example 1 (dual-cluster big.LITTLE system 32-bit):
cpus {
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index b1f8a73e5a94..eb315b6ea7fd 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -6,6 +6,8 @@
config ARM_BIG_LITTLE_CPUFREQ
tristate "Generic ARM big LITTLE CPUfreq driver"
depends on (ARM_CPU_TOPOLOGY || ARM64) && HAVE_CLK
+ # if CPU_THERMAL is on and THERMAL=m, ARM_BIT_LITTLE_CPUFREQ cannot be =y
+ depends on !CPU_THERMAL || THERMAL
select PM_OPP
help
This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index 158b3c237b9a..5940eb95b6a9 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -23,6 +23,7 @@
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/cpumask.h>
+#include <linux/cpu_cooling.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -55,6 +56,7 @@ static bool bL_switching_enabled;
#define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq)
#define VIRT_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq >> 1 : freq)
+static struct thermal_cooling_device *cdev[MAX_CLUSTERS];
static struct cpufreq_arm_bL_ops *arm_bL_ops;
static struct clk *clk[MAX_CLUSTERS];
static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1];
@@ -494,6 +496,12 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy)
static int bL_cpufreq_exit(struct cpufreq_policy *policy)
{
struct device *cpu_dev;
+ int cur_cluster = cpu_to_cluster(policy->cpu);
+
+ if (cur_cluster < MAX_CLUSTERS) {
+ cpufreq_cooling_unregister(cdev[cur_cluster]);
+ cdev[cur_cluster] = NULL;
+ }
cpu_dev = get_cpu_device(policy->cpu);
if (!cpu_dev) {
@@ -508,6 +516,38 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy)
return 0;
}
+static void bL_cpufreq_ready(struct cpufreq_policy *policy)
+{
+ struct device *cpu_dev = get_cpu_device(policy->cpu);
+ int cur_cluster = cpu_to_cluster(policy->cpu);
+ struct device_node *np;
+
+ /* Do not register a cpu_cooling device if we are in IKS mode */
+ if (cur_cluster >= MAX_CLUSTERS)
+ return;
+
+ np = of_node_get(cpu_dev->of_node);
+ if (WARN_ON(!np))
+ return;
+
+ if (of_find_property(np, "#cooling-cells", NULL)) {
+ u32 power_coefficient = 0;
+
+ of_property_read_u32(np, "dynamic-power-coefficient",
+ &power_coefficient);
+
+ cdev[cur_cluster] = of_cpufreq_power_cooling_register(np,
+ policy->related_cpus, power_coefficient, NULL);
+ if (IS_ERR(cdev[cur_cluster])) {
+ dev_err(cpu_dev,
+ "running cpufreq without cooling device: %ld\n",
+ PTR_ERR(cdev[cur_cluster]));
+ cdev[cur_cluster] = NULL;
+ }
+ }
+ of_node_put(np);
+}
+
static struct cpufreq_driver bL_cpufreq_driver = {
.name = "arm-big-little",
.flags = CPUFREQ_STICKY |
@@ -518,6 +558,7 @@ static struct cpufreq_driver bL_cpufreq_driver = {
.get = bL_cpufreq_get_rate,
.init = bL_cpufreq_init,
.exit = bL_cpufreq_exit,
+ .ready = bL_cpufreq_ready,
.attr = cpufreq_generic_attr,
};
diff --git a/linaro/configs/vexpress64.conf b/linaro/configs/vexpress64.conf
index 1744a88ba417..f7e16752551e 100644
--- a/linaro/configs/vexpress64.conf
+++ b/linaro/configs/vexpress64.conf
@@ -107,3 +107,12 @@ CONFIG_SND_SOC_SPDIF=y
CONFIG_SND_SIMPLE_CARD=y
CONFIG_DMADEVICES=y
CONFIG_PL330_DMA=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_CPU_THERMAL=y
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_PM_DEVFREQ=y
+CONFIG_DEVFREQ_THERMAL=y
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+CONFIG_DEVFREQ_GOV_PERFORMANCE=y