162306a36Sopenharmony_ci========================================== 262306a36Sopenharmony_ciCPU capacity bindings 362306a36Sopenharmony_ci========================================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci========================================== 662306a36Sopenharmony_ci1 - Introduction 762306a36Sopenharmony_ci========================================== 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciSome systems may be configured to have cpus with different power/performance 1062306a36Sopenharmony_cicharacteristics within the same chip. In this case, additional information has 1162306a36Sopenharmony_cito be made available to the kernel for it to be aware of such differences and 1262306a36Sopenharmony_citake decisions accordingly. 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci========================================== 1562306a36Sopenharmony_ci2 - CPU capacity definition 1662306a36Sopenharmony_ci========================================== 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ciCPU capacity is a number that provides the scheduler information about CPUs 1962306a36Sopenharmony_ciheterogeneity. Such heterogeneity can come from micro-architectural differences 2062306a36Sopenharmony_ci(e.g., ARM big.LITTLE systems) or maximum frequency at which CPUs can run 2162306a36Sopenharmony_ci(e.g., SMP systems with multiple frequency domains). Heterogeneity in this 2262306a36Sopenharmony_cicontext is about differing performance characteristics; this binding tries to 2362306a36Sopenharmony_cicapture a first-order approximation of the relative performance of CPUs. 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ciCPU capacities are obtained by running a suitable benchmark. This binding makes 2662306a36Sopenharmony_cino guarantees on the validity or suitability of any particular benchmark, the 2762306a36Sopenharmony_cifinal capacity should, however, be: 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci* A "single-threaded" or CPU affine benchmark 3062306a36Sopenharmony_ci* Divided by the running frequency of the CPU executing the benchmark 3162306a36Sopenharmony_ci* Not subject to dynamic frequency scaling of the CPU 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ciFor the time being we however advise usage of the Dhrystone benchmark. What 3462306a36Sopenharmony_ciabove thus becomes: 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ciCPU capacities are obtained by running the Dhrystone benchmark on each CPU at 3762306a36Sopenharmony_cimax frequency (with caches enabled). The obtained DMIPS score is then divided 3862306a36Sopenharmony_ciby the frequency (in MHz) at which the benchmark has been run, so that 3962306a36Sopenharmony_ciDMIPS/MHz are obtained. Such values are then normalized w.r.t. the highest 4062306a36Sopenharmony_ciscore obtained in the system. 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci========================================== 4362306a36Sopenharmony_ci3 - capacity-dmips-mhz 4462306a36Sopenharmony_ci========================================== 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cicapacity-dmips-mhz is an optional cpu node [1] property: u32 value 4762306a36Sopenharmony_cirepresenting CPU capacity expressed in normalized DMIPS/MHz. At boot time, the 4862306a36Sopenharmony_cimaximum frequency available to the cpu is then used to calculate the capacity 4962306a36Sopenharmony_civalue internally used by the kernel. 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cicapacity-dmips-mhz property is all-or-nothing: if it is specified for a cpu 5262306a36Sopenharmony_cinode, it has to be specified for every other cpu nodes, or the system will 5362306a36Sopenharmony_cifall back to the default capacity value for every CPU. If cpufreq is not 5462306a36Sopenharmony_ciavailable, final capacities are calculated by directly using capacity-dmips- 5562306a36Sopenharmony_cimhz values (normalized w.r.t. the highest value found while parsing the DT). 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci=========================================== 5862306a36Sopenharmony_ci4 - Examples 5962306a36Sopenharmony_ci=========================================== 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ciExample 1 (ARM 64-bit, 6-cpu system, two clusters): 6262306a36Sopenharmony_ciThe capacities-dmips-mhz or DMIPS/MHz values (scaled to 1024) 6362306a36Sopenharmony_ciare 1024 and 578 for cluster0 and cluster1. Further normalization 6462306a36Sopenharmony_ciis done by the operating system based on cluster0@max-freq=1100 and 6562306a36Sopenharmony_cicluster1@max-freq=850, final capacities are 1024 for cluster0 and 6662306a36Sopenharmony_ci446 for cluster1 (578*850/1100). 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cicpus { 6962306a36Sopenharmony_ci #address-cells = <2>; 7062306a36Sopenharmony_ci #size-cells = <0>; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci cpu-map { 7362306a36Sopenharmony_ci cluster0 { 7462306a36Sopenharmony_ci core0 { 7562306a36Sopenharmony_ci cpu = <&A57_0>; 7662306a36Sopenharmony_ci }; 7762306a36Sopenharmony_ci core1 { 7862306a36Sopenharmony_ci cpu = <&A57_1>; 7962306a36Sopenharmony_ci }; 8062306a36Sopenharmony_ci }; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci cluster1 { 8362306a36Sopenharmony_ci core0 { 8462306a36Sopenharmony_ci cpu = <&A53_0>; 8562306a36Sopenharmony_ci }; 8662306a36Sopenharmony_ci core1 { 8762306a36Sopenharmony_ci cpu = <&A53_1>; 8862306a36Sopenharmony_ci }; 8962306a36Sopenharmony_ci core2 { 9062306a36Sopenharmony_ci cpu = <&A53_2>; 9162306a36Sopenharmony_ci }; 9262306a36Sopenharmony_ci core3 { 9362306a36Sopenharmony_ci cpu = <&A53_3>; 9462306a36Sopenharmony_ci }; 9562306a36Sopenharmony_ci }; 9662306a36Sopenharmony_ci }; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci idle-states { 9962306a36Sopenharmony_ci entry-method = "psci"; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci CPU_SLEEP_0: cpu-sleep-0 { 10262306a36Sopenharmony_ci compatible = "arm,idle-state"; 10362306a36Sopenharmony_ci arm,psci-suspend-param = <0x0010000>; 10462306a36Sopenharmony_ci local-timer-stop; 10562306a36Sopenharmony_ci entry-latency-us = <100>; 10662306a36Sopenharmony_ci exit-latency-us = <250>; 10762306a36Sopenharmony_ci min-residency-us = <150>; 10862306a36Sopenharmony_ci }; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci CLUSTER_SLEEP_0: cluster-sleep-0 { 11162306a36Sopenharmony_ci compatible = "arm,idle-state"; 11262306a36Sopenharmony_ci arm,psci-suspend-param = <0x1010000>; 11362306a36Sopenharmony_ci local-timer-stop; 11462306a36Sopenharmony_ci entry-latency-us = <800>; 11562306a36Sopenharmony_ci exit-latency-us = <700>; 11662306a36Sopenharmony_ci min-residency-us = <2500>; 11762306a36Sopenharmony_ci }; 11862306a36Sopenharmony_ci }; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci A57_0: cpu@0 { 12162306a36Sopenharmony_ci compatible = "arm,cortex-a57"; 12262306a36Sopenharmony_ci reg = <0x0 0x0>; 12362306a36Sopenharmony_ci device_type = "cpu"; 12462306a36Sopenharmony_ci enable-method = "psci"; 12562306a36Sopenharmony_ci next-level-cache = <&A57_L2>; 12662306a36Sopenharmony_ci clocks = <&scpi_dvfs 0>; 12762306a36Sopenharmony_ci cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 12862306a36Sopenharmony_ci capacity-dmips-mhz = <1024>; 12962306a36Sopenharmony_ci }; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci A57_1: cpu@1 { 13262306a36Sopenharmony_ci compatible = "arm,cortex-a57"; 13362306a36Sopenharmony_ci reg = <0x0 0x1>; 13462306a36Sopenharmony_ci device_type = "cpu"; 13562306a36Sopenharmony_ci enable-method = "psci"; 13662306a36Sopenharmony_ci next-level-cache = <&A57_L2>; 13762306a36Sopenharmony_ci clocks = <&scpi_dvfs 0>; 13862306a36Sopenharmony_ci cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 13962306a36Sopenharmony_ci capacity-dmips-mhz = <1024>; 14062306a36Sopenharmony_ci }; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci A53_0: cpu@100 { 14362306a36Sopenharmony_ci compatible = "arm,cortex-a53"; 14462306a36Sopenharmony_ci reg = <0x0 0x100>; 14562306a36Sopenharmony_ci device_type = "cpu"; 14662306a36Sopenharmony_ci enable-method = "psci"; 14762306a36Sopenharmony_ci next-level-cache = <&A53_L2>; 14862306a36Sopenharmony_ci clocks = <&scpi_dvfs 1>; 14962306a36Sopenharmony_ci cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 15062306a36Sopenharmony_ci capacity-dmips-mhz = <578>; 15162306a36Sopenharmony_ci }; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci A53_1: cpu@101 { 15462306a36Sopenharmony_ci compatible = "arm,cortex-a53"; 15562306a36Sopenharmony_ci reg = <0x0 0x101>; 15662306a36Sopenharmony_ci device_type = "cpu"; 15762306a36Sopenharmony_ci enable-method = "psci"; 15862306a36Sopenharmony_ci next-level-cache = <&A53_L2>; 15962306a36Sopenharmony_ci clocks = <&scpi_dvfs 1>; 16062306a36Sopenharmony_ci cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 16162306a36Sopenharmony_ci capacity-dmips-mhz = <578>; 16262306a36Sopenharmony_ci }; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci A53_2: cpu@102 { 16562306a36Sopenharmony_ci compatible = "arm,cortex-a53"; 16662306a36Sopenharmony_ci reg = <0x0 0x102>; 16762306a36Sopenharmony_ci device_type = "cpu"; 16862306a36Sopenharmony_ci enable-method = "psci"; 16962306a36Sopenharmony_ci next-level-cache = <&A53_L2>; 17062306a36Sopenharmony_ci clocks = <&scpi_dvfs 1>; 17162306a36Sopenharmony_ci cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 17262306a36Sopenharmony_ci capacity-dmips-mhz = <578>; 17362306a36Sopenharmony_ci }; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci A53_3: cpu@103 { 17662306a36Sopenharmony_ci compatible = "arm,cortex-a53"; 17762306a36Sopenharmony_ci reg = <0x0 0x103>; 17862306a36Sopenharmony_ci device_type = "cpu"; 17962306a36Sopenharmony_ci enable-method = "psci"; 18062306a36Sopenharmony_ci next-level-cache = <&A53_L2>; 18162306a36Sopenharmony_ci clocks = <&scpi_dvfs 1>; 18262306a36Sopenharmony_ci cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; 18362306a36Sopenharmony_ci capacity-dmips-mhz = <578>; 18462306a36Sopenharmony_ci }; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci A57_L2: l2-cache0 { 18762306a36Sopenharmony_ci compatible = "cache"; 18862306a36Sopenharmony_ci }; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci A53_L2: l2-cache1 { 19162306a36Sopenharmony_ci compatible = "cache"; 19262306a36Sopenharmony_ci }; 19362306a36Sopenharmony_ci}; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ciExample 2 (ARM 32-bit, 4-cpu system, two clusters, 19662306a36Sopenharmony_ci cpus 0,1@1GHz, cpus 2,3@500MHz): 19762306a36Sopenharmony_cicapacities-dmips-mhz are scaled w.r.t. 2 (cpu@0 and cpu@1), this means that first 19862306a36Sopenharmony_cicpu@0 and cpu@1 are twice fast than cpu@2 and cpu@3 (at the same frequency) 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_cicpus { 20162306a36Sopenharmony_ci #address-cells = <1>; 20262306a36Sopenharmony_ci #size-cells = <0>; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci cpu0: cpu@0 { 20562306a36Sopenharmony_ci device_type = "cpu"; 20662306a36Sopenharmony_ci compatible = "arm,cortex-a15"; 20762306a36Sopenharmony_ci reg = <0>; 20862306a36Sopenharmony_ci capacity-dmips-mhz = <2>; 20962306a36Sopenharmony_ci }; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci cpu1: cpu@1 { 21262306a36Sopenharmony_ci device_type = "cpu"; 21362306a36Sopenharmony_ci compatible = "arm,cortex-a15"; 21462306a36Sopenharmony_ci reg = <1>; 21562306a36Sopenharmony_ci capacity-dmips-mhz = <2>; 21662306a36Sopenharmony_ci }; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci cpu2: cpu@2 { 21962306a36Sopenharmony_ci device_type = "cpu"; 22062306a36Sopenharmony_ci compatible = "arm,cortex-a15"; 22162306a36Sopenharmony_ci reg = <0x100>; 22262306a36Sopenharmony_ci capacity-dmips-mhz = <1>; 22362306a36Sopenharmony_ci }; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci cpu3: cpu@3 { 22662306a36Sopenharmony_ci device_type = "cpu"; 22762306a36Sopenharmony_ci compatible = "arm,cortex-a15"; 22862306a36Sopenharmony_ci reg = <0x101>; 22962306a36Sopenharmony_ci capacity-dmips-mhz = <1>; 23062306a36Sopenharmony_ci }; 23162306a36Sopenharmony_ci}; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci=========================================== 23462306a36Sopenharmony_ci5 - References 23562306a36Sopenharmony_ci=========================================== 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci[1] ARM Linux Kernel documentation - CPUs bindings 23862306a36Sopenharmony_ci Documentation/devicetree/bindings/arm/cpus.yaml 239