arm64: topology: Allow specifying the CPU efficiency from device tree
The efficiency of a CPU can vary across SoCs depending on the cache size,
bus interconnect frequencies etc. Allow specifying this from the device
tree. This value overrides the default values hardcoded in the efficiency
table.
Change-Id: Ie9ba69e11317e6eb6462630226355747d1def646
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index e6782d5..38271eb 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -220,6 +220,20 @@
property identifying a 64-bit zero-initialised
memory location.
+ - efficiency
+ Usage: optional.
+ Value type: <u32>
+ Definition:
+ # Specifies the CPU efficiency. The CPU efficiency is
+ a unit less number and it is intended to show relative
+ performance of CPUs when normalized for clock frequency
+ (instructions per cycle performance).
+
+ The efficiency of a CPU can vary across SoCs depending
+ on the cache size, bus interconnect frequencies etc.
+ This value overrides the default efficiency value
+ defined for the corresponding CPU architecture.
+
- qcom,saw
Usage: required for systems that have an "enable-method"
property value of "qcom,kpss-acc-v1" or
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index e562e0f..67fc833 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -278,6 +278,7 @@
for_each_possible_cpu(cpu) {
const u32 *rate;
int len;
+ u32 efficiency;
/* Too early to use cpu->of_node */
cn = of_get_cpu_node(cpu, NULL);
@@ -286,16 +287,29 @@
continue;
}
- for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
- if (of_device_is_compatible(cn, cpu_eff->compatible))
- break;
+ /*
+ * The CPU efficiency value passed from the device tree
+ * overrides the value defined in the table_efficiency[]
+ */
+ if (of_property_read_u32(cn, "efficiency", &efficiency) < 0) {
- if (cpu_eff->compatible == NULL) {
- pr_warn("%s: Unknown CPU type\n", cn->full_name);
- continue;
+ for (cpu_eff = table_efficiency;
+ cpu_eff->compatible; cpu_eff++)
+
+ if (of_device_is_compatible(cn,
+ cpu_eff->compatible))
+ break;
+
+ if (cpu_eff->compatible == NULL) {
+ pr_warn("%s: Unknown CPU type\n",
+ cn->full_name);
+ continue;
+ }
+
+ efficiency = cpu_eff->efficiency;
}
- per_cpu(cpu_efficiency, cpu) = cpu_eff->efficiency;
+ per_cpu(cpu_efficiency, cpu) = efficiency;
rate = of_get_property(cn, "clock-frequency", &len);
if (!rate || len != 4) {
@@ -304,7 +318,7 @@
continue;
}
- capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
+ capacity = ((be32_to_cpup(rate)) >> 20) * efficiency;
/* Save min capacity of the system */
if (capacity < min_capacity)