18c2ecf20Sopenharmony_ci==========================================
28c2ecf20Sopenharmony_ciARM CPUs capacity bindings
38c2ecf20Sopenharmony_ci==========================================
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci==========================================
68c2ecf20Sopenharmony_ci1 - Introduction
78c2ecf20Sopenharmony_ci==========================================
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ciARM systems may be configured to have cpus with different power/performance
108c2ecf20Sopenharmony_cicharacteristics within the same chip. In this case, additional information has
118c2ecf20Sopenharmony_cito be made available to the kernel for it to be aware of such differences and
128c2ecf20Sopenharmony_citake decisions accordingly.
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci==========================================
158c2ecf20Sopenharmony_ci2 - CPU capacity definition
168c2ecf20Sopenharmony_ci==========================================
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ciCPU capacity is a number that provides the scheduler information about CPUs
198c2ecf20Sopenharmony_ciheterogeneity. Such heterogeneity can come from micro-architectural differences
208c2ecf20Sopenharmony_ci(e.g., ARM big.LITTLE systems) or maximum frequency at which CPUs can run
218c2ecf20Sopenharmony_ci(e.g., SMP systems with multiple frequency domains). Heterogeneity in this
228c2ecf20Sopenharmony_cicontext is about differing performance characteristics; this binding tries to
238c2ecf20Sopenharmony_cicapture a first-order approximation of the relative performance of CPUs.
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ciCPU capacities are obtained by running a suitable benchmark. This binding makes
268c2ecf20Sopenharmony_cino guarantees on the validity or suitability of any particular benchmark, the
278c2ecf20Sopenharmony_cifinal capacity should, however, be:
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci* A "single-threaded" or CPU affine benchmark
308c2ecf20Sopenharmony_ci* Divided by the running frequency of the CPU executing the benchmark
318c2ecf20Sopenharmony_ci* Not subject to dynamic frequency scaling of the CPU
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ciFor the time being we however advise usage of the Dhrystone benchmark. What
348c2ecf20Sopenharmony_ciabove thus becomes:
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ciCPU capacities are obtained by running the Dhrystone benchmark on each CPU at
378c2ecf20Sopenharmony_cimax frequency (with caches enabled). The obtained DMIPS score is then divided
388c2ecf20Sopenharmony_ciby the frequency (in MHz) at which the benchmark has been run, so that
398c2ecf20Sopenharmony_ciDMIPS/MHz are obtained.  Such values are then normalized w.r.t. the highest
408c2ecf20Sopenharmony_ciscore obtained in the system.
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci==========================================
438c2ecf20Sopenharmony_ci3 - capacity-dmips-mhz
448c2ecf20Sopenharmony_ci==========================================
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_cicapacity-dmips-mhz is an optional cpu node [1] property: u32 value
478c2ecf20Sopenharmony_cirepresenting CPU capacity expressed in normalized DMIPS/MHz. At boot time, the
488c2ecf20Sopenharmony_cimaximum frequency available to the cpu is then used to calculate the capacity
498c2ecf20Sopenharmony_civalue internally used by the kernel.
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cicapacity-dmips-mhz property is all-or-nothing: if it is specified for a cpu
528c2ecf20Sopenharmony_cinode, it has to be specified for every other cpu nodes, or the system will
538c2ecf20Sopenharmony_cifall back to the default capacity value for every CPU. If cpufreq is not
548c2ecf20Sopenharmony_ciavailable, final capacities are calculated by directly using capacity-dmips-
558c2ecf20Sopenharmony_cimhz values (normalized w.r.t. the highest value found while parsing the DT).
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci===========================================
588c2ecf20Sopenharmony_ci4 - Examples
598c2ecf20Sopenharmony_ci===========================================
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ciExample 1 (ARM 64-bit, 6-cpu system, two clusters):
628c2ecf20Sopenharmony_ciThe capacities-dmips-mhz or DMIPS/MHz values (scaled to 1024)
638c2ecf20Sopenharmony_ciare 1024 and 578 for cluster0 and cluster1. Further normalization
648c2ecf20Sopenharmony_ciis done by the operating system based on cluster0@max-freq=1100 and
658c2ecf20Sopenharmony_cicuster1@max-freq=850, final capacities are 1024 for cluster0 and
668c2ecf20Sopenharmony_ci446 for cluster1 (576*850/1100).
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cicpus {
698c2ecf20Sopenharmony_ci	#address-cells = <2>;
708c2ecf20Sopenharmony_ci	#size-cells = <0>;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	cpu-map {
738c2ecf20Sopenharmony_ci		cluster0 {
748c2ecf20Sopenharmony_ci			core0 {
758c2ecf20Sopenharmony_ci				cpu = <&A57_0>;
768c2ecf20Sopenharmony_ci			};
778c2ecf20Sopenharmony_ci			core1 {
788c2ecf20Sopenharmony_ci				cpu = <&A57_1>;
798c2ecf20Sopenharmony_ci			};
808c2ecf20Sopenharmony_ci		};
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci		cluster1 {
838c2ecf20Sopenharmony_ci			core0 {
848c2ecf20Sopenharmony_ci				cpu = <&A53_0>;
858c2ecf20Sopenharmony_ci			};
868c2ecf20Sopenharmony_ci			core1 {
878c2ecf20Sopenharmony_ci				cpu = <&A53_1>;
888c2ecf20Sopenharmony_ci			};
898c2ecf20Sopenharmony_ci			core2 {
908c2ecf20Sopenharmony_ci				cpu = <&A53_2>;
918c2ecf20Sopenharmony_ci			};
928c2ecf20Sopenharmony_ci			core3 {
938c2ecf20Sopenharmony_ci				cpu = <&A53_3>;
948c2ecf20Sopenharmony_ci			};
958c2ecf20Sopenharmony_ci		};
968c2ecf20Sopenharmony_ci	};
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	idle-states {
998c2ecf20Sopenharmony_ci		entry-method = "psci";
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci		CPU_SLEEP_0: cpu-sleep-0 {
1028c2ecf20Sopenharmony_ci			compatible = "arm,idle-state";
1038c2ecf20Sopenharmony_ci			arm,psci-suspend-param = <0x0010000>;
1048c2ecf20Sopenharmony_ci			local-timer-stop;
1058c2ecf20Sopenharmony_ci			entry-latency-us = <100>;
1068c2ecf20Sopenharmony_ci			exit-latency-us = <250>;
1078c2ecf20Sopenharmony_ci			min-residency-us = <150>;
1088c2ecf20Sopenharmony_ci		};
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci		CLUSTER_SLEEP_0: cluster-sleep-0 {
1118c2ecf20Sopenharmony_ci			compatible = "arm,idle-state";
1128c2ecf20Sopenharmony_ci			arm,psci-suspend-param = <0x1010000>;
1138c2ecf20Sopenharmony_ci			local-timer-stop;
1148c2ecf20Sopenharmony_ci			entry-latency-us = <800>;
1158c2ecf20Sopenharmony_ci			exit-latency-us = <700>;
1168c2ecf20Sopenharmony_ci			min-residency-us = <2500>;
1178c2ecf20Sopenharmony_ci		};
1188c2ecf20Sopenharmony_ci	};
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	A57_0: cpu@0 {
1218c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a57";
1228c2ecf20Sopenharmony_ci		reg = <0x0 0x0>;
1238c2ecf20Sopenharmony_ci		device_type = "cpu";
1248c2ecf20Sopenharmony_ci		enable-method = "psci";
1258c2ecf20Sopenharmony_ci		next-level-cache = <&A57_L2>;
1268c2ecf20Sopenharmony_ci		clocks = <&scpi_dvfs 0>;
1278c2ecf20Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
1288c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <1024>;
1298c2ecf20Sopenharmony_ci	};
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	A57_1: cpu@1 {
1328c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a57";
1338c2ecf20Sopenharmony_ci		reg = <0x0 0x1>;
1348c2ecf20Sopenharmony_ci		device_type = "cpu";
1358c2ecf20Sopenharmony_ci		enable-method = "psci";
1368c2ecf20Sopenharmony_ci		next-level-cache = <&A57_L2>;
1378c2ecf20Sopenharmony_ci		clocks = <&scpi_dvfs 0>;
1388c2ecf20Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
1398c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <1024>;
1408c2ecf20Sopenharmony_ci	};
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	A53_0: cpu@100 {
1438c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a53";
1448c2ecf20Sopenharmony_ci		reg = <0x0 0x100>;
1458c2ecf20Sopenharmony_ci		device_type = "cpu";
1468c2ecf20Sopenharmony_ci		enable-method = "psci";
1478c2ecf20Sopenharmony_ci		next-level-cache = <&A53_L2>;
1488c2ecf20Sopenharmony_ci		clocks = <&scpi_dvfs 1>;
1498c2ecf20Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
1508c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <578>;
1518c2ecf20Sopenharmony_ci	};
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	A53_1: cpu@101 {
1548c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a53";
1558c2ecf20Sopenharmony_ci		reg = <0x0 0x101>;
1568c2ecf20Sopenharmony_ci		device_type = "cpu";
1578c2ecf20Sopenharmony_ci		enable-method = "psci";
1588c2ecf20Sopenharmony_ci		next-level-cache = <&A53_L2>;
1598c2ecf20Sopenharmony_ci		clocks = <&scpi_dvfs 1>;
1608c2ecf20Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
1618c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <578>;
1628c2ecf20Sopenharmony_ci	};
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	A53_2: cpu@102 {
1658c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a53";
1668c2ecf20Sopenharmony_ci		reg = <0x0 0x102>;
1678c2ecf20Sopenharmony_ci		device_type = "cpu";
1688c2ecf20Sopenharmony_ci		enable-method = "psci";
1698c2ecf20Sopenharmony_ci		next-level-cache = <&A53_L2>;
1708c2ecf20Sopenharmony_ci		clocks = <&scpi_dvfs 1>;
1718c2ecf20Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
1728c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <578>;
1738c2ecf20Sopenharmony_ci	};
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	A53_3: cpu@103 {
1768c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a53";
1778c2ecf20Sopenharmony_ci		reg = <0x0 0x103>;
1788c2ecf20Sopenharmony_ci		device_type = "cpu";
1798c2ecf20Sopenharmony_ci		enable-method = "psci";
1808c2ecf20Sopenharmony_ci		next-level-cache = <&A53_L2>;
1818c2ecf20Sopenharmony_ci		clocks = <&scpi_dvfs 1>;
1828c2ecf20Sopenharmony_ci		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
1838c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <578>;
1848c2ecf20Sopenharmony_ci	};
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	A57_L2: l2-cache0 {
1878c2ecf20Sopenharmony_ci		compatible = "cache";
1888c2ecf20Sopenharmony_ci	};
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	A53_L2: l2-cache1 {
1918c2ecf20Sopenharmony_ci		compatible = "cache";
1928c2ecf20Sopenharmony_ci	};
1938c2ecf20Sopenharmony_ci};
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ciExample 2 (ARM 32-bit, 4-cpu system, two clusters,
1968c2ecf20Sopenharmony_ci	   cpus 0,1@1GHz, cpus 2,3@500MHz):
1978c2ecf20Sopenharmony_cicapacities-dmips-mhz are scaled w.r.t. 2 (cpu@0 and cpu@1), this means that first
1988c2ecf20Sopenharmony_cicpu@0 and cpu@1 are twice fast than cpu@2 and cpu@3 (at the same frequency)
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cicpus {
2018c2ecf20Sopenharmony_ci	#address-cells = <1>;
2028c2ecf20Sopenharmony_ci	#size-cells = <0>;
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci	cpu0: cpu@0 {
2058c2ecf20Sopenharmony_ci		device_type = "cpu";
2068c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a15";
2078c2ecf20Sopenharmony_ci		reg = <0>;
2088c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <2>;
2098c2ecf20Sopenharmony_ci	};
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	cpu1: cpu@1 {
2128c2ecf20Sopenharmony_ci		device_type = "cpu";
2138c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a15";
2148c2ecf20Sopenharmony_ci		reg = <1>;
2158c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <2>;
2168c2ecf20Sopenharmony_ci	};
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	cpu2: cpu@2 {
2198c2ecf20Sopenharmony_ci		device_type = "cpu";
2208c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a15";
2218c2ecf20Sopenharmony_ci		reg = <0x100>;
2228c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <1>;
2238c2ecf20Sopenharmony_ci	};
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	cpu3: cpu@3 {
2268c2ecf20Sopenharmony_ci		device_type = "cpu";
2278c2ecf20Sopenharmony_ci		compatible = "arm,cortex-a15";
2288c2ecf20Sopenharmony_ci		reg = <0x101>;
2298c2ecf20Sopenharmony_ci		capacity-dmips-mhz = <1>;
2308c2ecf20Sopenharmony_ci	};
2318c2ecf20Sopenharmony_ci};
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci===========================================
2348c2ecf20Sopenharmony_ci5 - References
2358c2ecf20Sopenharmony_ci===========================================
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci[1] ARM Linux Kernel documentation - CPUs bindings
2388c2ecf20Sopenharmony_ci    Documentation/devicetree/bindings/arm/cpus.yaml
239