All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v5 0/3] ARM: defining idle states DT bindings
@ 2014-03-18 11:28 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-18 11:28 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
	Lorenzo Pieralisi, Russell King, Sebastian Capella,
	Nicolas Pitre, Daniel Lezcano, linux-arm-kernel, Grant Likely,
	Dave Martin, Charles Garcia Tobin, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Vincent Guittot, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd, Amit Kucheria

This is v5 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/233478.html

This patchset depends on the following bindings to be approved and augmented
to cater for hierarchical power domains in DT:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-March/237479.html

Changes in v5:

- Added missing power-domain property in cpu nodes
- Reworded index property definition
- Added -us extensions to idle state nodes latency entries
- Changed PSCI entry-method compatible string
- Reworded and simplified hierarchical idle states definition
- Reworded min-residency definition

Changes in v4:

- Made entry-method global
- Renamed power_state parameter
- Augmented examples with retention states and node tags
- Reworded index property definition in the state node
- Changed the naming scheme for state nodes to default DT
- Defined idle_standby idle state (need not be listed)
- Clarified SBSA nomenclature and usage in the bindings

Changes in v3:

- Renamed C-states to "idle states" in patches and cover letter
- Added SBSA definitions
- Added power_state parameter to PSCI
- Removed OPP dependency
- Split latency into entry/exit latencies
- Reintroduced processor and cache retention boolean
- Made power_state generic parameter for all entry methods
- Redefined idle state hierarchy

Changes in v2:

- Updated cache bindings according to review
- Added power domain phandle to cache bindings
- Added power domains to C-states bindings
- Removed useless reg property from C-states bindings
- Removed cpu-map references from C-states bindings
- Added dependency on OPP in C-states parameters
- Added C-state state hierarchy

ARM based systems embed power management HW that allows SW to enter
low-power states according to run-time criteria based on parameters (eg
power state entry/exit latency) that define how an idle state has to be
managed and its respective properties. ARM partners implement HW power
management schemes through custom HW, with power controllers and relative
control mechanisms differing on both HW implementations and the way SW can
control them. This differentiation forces PM software in the kernel to cope
with states differences in power management drivers, which cause code
fragmentation and duplication of functionality.

Most of the power control scheme HW parameters are not probeable on ARM
platforms from a SW point of view, hence, in order to tackle the drivers
fragmentation problem, this patch series defines device tree bindings to
describe idle states parameters on ARM platforms.

Device tree bindings for idle states also require the introduction of device
tree bindings for processor caches, since idle states entry/exit require
SW cache maintainance; in some ARM systems, where firmware does not
support power down interfaces, cache maintainance must be carried out in the
OS power management layer, which then requires a description of the cache
topology through device tree nodes.

Idle states device tree standardization shares most of the concepts and
definitions with the ongoing ACPI ARM C-state bindings proposal so that
both standards can contain a coherent set of parameters, simplifying the
way SW will have to handle the respective device drivers.

Lorenzo Pieralisi (3):
  Documentation: devicetree: psci: define CPU suspend parameter
  Documentation: arm: add cache DT bindings
  Documentation: arm: define DT idle states bindings

 Documentation/devicetree/bindings/arm/cache.txt    | 166 +++++
 Documentation/devicetree/bindings/arm/cpus.txt     |  18 +
 .../devicetree/bindings/arm/idle-states.txt        | 771 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/psci.txt     |  11 +
 4 files changed, 966 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cache.txt
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt

-- 
1.8.4

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 0/3] ARM: defining idle states DT bindings
@ 2014-03-18 11:28 ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-18 11:28 UTC (permalink / raw)
  To: linux-arm-kernel

This is v5 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-February/233478.html

This patchset depends on the following bindings to be approved and augmented
to cater for hierarchical power domains in DT:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-March/237479.html

Changes in v5:

- Added missing power-domain property in cpu nodes
- Reworded index property definition
- Added -us extensions to idle state nodes latency entries
- Changed PSCI entry-method compatible string
- Reworded and simplified hierarchical idle states definition
- Reworded min-residency definition

Changes in v4:

- Made entry-method global
- Renamed power_state parameter
- Augmented examples with retention states and node tags
- Reworded index property definition in the state node
- Changed the naming scheme for state nodes to default DT
- Defined idle_standby idle state (need not be listed)
- Clarified SBSA nomenclature and usage in the bindings

Changes in v3:

- Renamed C-states to "idle states" in patches and cover letter
- Added SBSA definitions
- Added power_state parameter to PSCI
- Removed OPP dependency
- Split latency into entry/exit latencies
- Reintroduced processor and cache retention boolean
- Made power_state generic parameter for all entry methods
- Redefined idle state hierarchy

Changes in v2:

- Updated cache bindings according to review
- Added power domain phandle to cache bindings
- Added power domains to C-states bindings
- Removed useless reg property from C-states bindings
- Removed cpu-map references from C-states bindings
- Added dependency on OPP in C-states parameters
- Added C-state state hierarchy

ARM based systems embed power management HW that allows SW to enter
low-power states according to run-time criteria based on parameters (eg
power state entry/exit latency) that define how an idle state has to be
managed and its respective properties. ARM partners implement HW power
management schemes through custom HW, with power controllers and relative
control mechanisms differing on both HW implementations and the way SW can
control them. This differentiation forces PM software in the kernel to cope
with states differences in power management drivers, which cause code
fragmentation and duplication of functionality.

Most of the power control scheme HW parameters are not probeable on ARM
platforms from a SW point of view, hence, in order to tackle the drivers
fragmentation problem, this patch series defines device tree bindings to
describe idle states parameters on ARM platforms.

Device tree bindings for idle states also require the introduction of device
tree bindings for processor caches, since idle states entry/exit require
SW cache maintainance; in some ARM systems, where firmware does not
support power down interfaces, cache maintainance must be carried out in the
OS power management layer, which then requires a description of the cache
topology through device tree nodes.

Idle states device tree standardization shares most of the concepts and
definitions with the ongoing ACPI ARM C-state bindings proposal so that
both standards can contain a coherent set of parameters, simplifying the
way SW will have to handle the respective device drivers.

Lorenzo Pieralisi (3):
  Documentation: devicetree: psci: define CPU suspend parameter
  Documentation: arm: add cache DT bindings
  Documentation: arm: define DT idle states bindings

 Documentation/devicetree/bindings/arm/cache.txt    | 166 +++++
 Documentation/devicetree/bindings/arm/cpus.txt     |  18 +
 .../devicetree/bindings/arm/idle-states.txt        | 771 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/psci.txt     |  11 +
 4 files changed, 966 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cache.txt
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt

-- 
1.8.4

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 1/3] Documentation: devicetree: psci: define CPU suspend parameter
  2014-03-18 11:28 ` Lorenzo Pieralisi
@ 2014-03-18 11:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-18 11:28 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
	Lorenzo Pieralisi, Russell King, Sebastian Capella,
	Nicolas Pitre, Daniel Lezcano, linux-arm-kernel, Grant Likely,
	Dave Martin, Charles Garcia Tobin, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Vincent Guittot, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd, Amit Kucheria

OS layers built on top of PSCI to enter low-power states require the
power_state parameter to be passed to the PSCI CPU suspend method.

This parameter is specific to a power state and platform specific,
therefore must be provided by firmware to the OS in order to enable
proper call sequence.

This patch adds a property in the PSCI bindings that describes how
the CPU suspend power_state parameter should be defined in DT in
all device nodes that rely on PSCI CPU suspend method usage.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/psci.txt | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/psci.txt b/Documentation/devicetree/bindings/arm/psci.txt
index 433afe9..797c48f 100644
--- a/Documentation/devicetree/bindings/arm/psci.txt
+++ b/Documentation/devicetree/bindings/arm/psci.txt
@@ -42,6 +42,14 @@ Main node optional properties:
 
  - migrate       : Function ID for MIGRATE operation
 
+Device tree nodes that require usage of PSCI CPU_SUSPEND function (ie idle
+states bindings[1]) must specify the following properties:
+
+- entry-method-param
+		Usage: Required for idle states bindings [1].
+		Value type: <u32>
+		Definition: power_state parameter to pass to the PSCI
+			    suspend call.
 
 Example:
 
@@ -53,3 +61,6 @@ Example:
 		cpu_on		= <0x95c10002>;
 		migrate		= <0x95c10003>;
 	};
+
+[1] Kernel documentation - ARM idle states bindings
+    Documentation/devicetree/bindings/arm/idle-states.txt
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 1/3] Documentation: devicetree: psci: define CPU suspend parameter
@ 2014-03-18 11:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-18 11:28 UTC (permalink / raw)
  To: linux-arm-kernel

OS layers built on top of PSCI to enter low-power states require the
power_state parameter to be passed to the PSCI CPU suspend method.

This parameter is specific to a power state and platform specific,
therefore must be provided by firmware to the OS in order to enable
proper call sequence.

This patch adds a property in the PSCI bindings that describes how
the CPU suspend power_state parameter should be defined in DT in
all device nodes that rely on PSCI CPU suspend method usage.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/psci.txt | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/psci.txt b/Documentation/devicetree/bindings/arm/psci.txt
index 433afe9..797c48f 100644
--- a/Documentation/devicetree/bindings/arm/psci.txt
+++ b/Documentation/devicetree/bindings/arm/psci.txt
@@ -42,6 +42,14 @@ Main node optional properties:
 
  - migrate       : Function ID for MIGRATE operation
 
+Device tree nodes that require usage of PSCI CPU_SUSPEND function (ie idle
+states bindings[1]) must specify the following properties:
+
+- entry-method-param
+		Usage: Required for idle states bindings [1].
+		Value type: <u32>
+		Definition: power_state parameter to pass to the PSCI
+			    suspend call.
 
 Example:
 
@@ -53,3 +61,6 @@ Example:
 		cpu_on		= <0x95c10002>;
 		migrate		= <0x95c10003>;
 	};
+
+[1] Kernel documentation - ARM idle states bindings
+    Documentation/devicetree/bindings/arm/idle-states.txt
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 2/3] Documentation: arm: add cache DT bindings
  2014-03-18 11:28 ` Lorenzo Pieralisi
@ 2014-03-18 11:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-18 11:28 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
	Lorenzo Pieralisi, Russell King, Sebastian Capella,
	Nicolas Pitre, Daniel Lezcano, linux-arm-kernel, Grant Likely,
	Dave Martin, Charles Garcia Tobin, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Vincent Guittot, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd, Amit Kucheria

On ARM systems the cache topology cannot be probed at runtime, in
particular, it is impossible to probe which CPUs share a given cache
level. Power management software requires this knowledge to implement
optimized power down sequences, hence this patch adds a document that
defines the DT cache bindings for ARM systems. The bindings supersede
cache bindings in the ePAPR (PowerPC bindings), because caches geometry for
architected caches is probeable on ARM systems. This patch also adds
properties that are specific to ARM architected caches to the existing ones
defined in the ePAPR v1.1, as bindings extensions.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/cache.txt | 166 ++++++++++++++++++++++++
 1 file changed, 166 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cache.txt

diff --git a/Documentation/devicetree/bindings/arm/cache.txt b/Documentation/devicetree/bindings/arm/cache.txt
new file mode 100644
index 0000000..b90fcc7
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/cache.txt
@@ -0,0 +1,166 @@
+==========================================
+ARM processors cache binding description
+==========================================
+
+Device tree bindings for cache nodes are already part of the ePAPR standard
+v1.1 ([2]) for PowerPC platforms. This document defines the cache bindings
+for caches on ARM processor systems.
+
+On ARM based systems most of the cache properties related to cache geometry
+are probeable in HW (please refer to the processor TRMs in [1] for register
+details), hence, unless otherwise stated, the properties defined in ePAPR for
+internal, multi-level and shared caches ([2], 3.7.3, 3.8) are to be considered
+superseded on ARM.
+
+On ARM, caches are either architected (directly controlled by the processor
+through coprocessor instructions and tightly coupled with the processor
+implementation) or unarchitected (controlled through a memory mapped
+interface, implemented as a stand-alone IP external to the processor
+implementation).
+
+This document provides the device tree bindings for ARM architected caches.
+
+- ARM architected cache node
+
+	Description: must be a direct child of the cpu node.
+		     A system can contain multiple architected cache nodes
+		     per cpu node, linked through the next-level-cache phandle.
+		     The next-level-cache property in the cpu node points to
+		     the first level of architected cache for the CPU.
+		     The next-level-cache links ordering must represent the
+		     system cache hierarchy in the system, with the upper
+		     cache level represented by a cache node with a missing
+		     next-level-cache property.
+
+	ARM architected cache node defines the following properties:
+
+	- compatible
+		Usage: Required
+		Value type: <string>
+		Definition: value shall be "arm,arch-cache".
+
+	- power-domain
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition: A phandle and power domain specifier as defined by
+			    bindings of power domain specified by [3].
+
+Example(dual-cluster big.LITTLE system 32-bit)
+
+	cpus {
+		#size-cells = <0>;
+		#address-cells = <1>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x0>;
+			next-level-cache = <&L1_0>;
+
+			L1_0: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+
+			L2_0: l2-cache {
+				compatible = "arm,arch-cache";
+			};
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x1>;
+			next-level-cache = <&L1_1>;
+
+			L1_1: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x2>;
+			next-level-cache = <&L1_2>;
+
+			L1_2: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x3>;
+			next-level-cache = <&L1_3>;
+
+			L1_3: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			next-level-cache = <&L1_4>;
+
+			L1_4: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+
+			L2_1: l2-cache {
+				compatible = "arm,arch-cache";
+			};
+		};
+
+		cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			next-level-cache = <&L1_5>;
+
+			L1_5: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+
+		cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x102>;
+			next-level-cache = <&L1_6>;
+
+			L1_6: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+
+		cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x103>;
+			next-level-cache = <&L1_7>;
+
+			L1_7: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+	};
+
+[1] ARM Architecture Reference Manuals
+    http://infocenter.arm.com/help/index.jsp
+
+[2] ePAPR standard
+    https://www.power.org/documentation/epapr-version-1-1/
+
+[3] Kernel documentation - power domain bindings
+    Documentation/devicetree/bindings/power/power_domain.txt
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 2/3] Documentation: arm: add cache DT bindings
@ 2014-03-18 11:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-18 11:28 UTC (permalink / raw)
  To: linux-arm-kernel

On ARM systems the cache topology cannot be probed at runtime, in
particular, it is impossible to probe which CPUs share a given cache
level. Power management software requires this knowledge to implement
optimized power down sequences, hence this patch adds a document that
defines the DT cache bindings for ARM systems. The bindings supersede
cache bindings in the ePAPR (PowerPC bindings), because caches geometry for
architected caches is probeable on ARM systems. This patch also adds
properties that are specific to ARM architected caches to the existing ones
defined in the ePAPR v1.1, as bindings extensions.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/cache.txt | 166 ++++++++++++++++++++++++
 1 file changed, 166 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cache.txt

diff --git a/Documentation/devicetree/bindings/arm/cache.txt b/Documentation/devicetree/bindings/arm/cache.txt
new file mode 100644
index 0000000..b90fcc7
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/cache.txt
@@ -0,0 +1,166 @@
+==========================================
+ARM processors cache binding description
+==========================================
+
+Device tree bindings for cache nodes are already part of the ePAPR standard
+v1.1 ([2]) for PowerPC platforms. This document defines the cache bindings
+for caches on ARM processor systems.
+
+On ARM based systems most of the cache properties related to cache geometry
+are probeable in HW (please refer to the processor TRMs in [1] for register
+details), hence, unless otherwise stated, the properties defined in ePAPR for
+internal, multi-level and shared caches ([2], 3.7.3, 3.8) are to be considered
+superseded on ARM.
+
+On ARM, caches are either architected (directly controlled by the processor
+through coprocessor instructions and tightly coupled with the processor
+implementation) or unarchitected (controlled through a memory mapped
+interface, implemented as a stand-alone IP external to the processor
+implementation).
+
+This document provides the device tree bindings for ARM architected caches.
+
+- ARM architected cache node
+
+	Description: must be a direct child of the cpu node.
+		     A system can contain multiple architected cache nodes
+		     per cpu node, linked through the next-level-cache phandle.
+		     The next-level-cache property in the cpu node points to
+		     the first level of architected cache for the CPU.
+		     The next-level-cache links ordering must represent the
+		     system cache hierarchy in the system, with the upper
+		     cache level represented by a cache node with a missing
+		     next-level-cache property.
+
+	ARM architected cache node defines the following properties:
+
+	- compatible
+		Usage: Required
+		Value type: <string>
+		Definition: value shall be "arm,arch-cache".
+
+	- power-domain
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition: A phandle and power domain specifier as defined by
+			    bindings of power domain specified by [3].
+
+Example(dual-cluster big.LITTLE system 32-bit)
+
+	cpus {
+		#size-cells = <0>;
+		#address-cells = <1>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x0>;
+			next-level-cache = <&L1_0>;
+
+			L1_0: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+
+			L2_0: l2-cache {
+				compatible = "arm,arch-cache";
+			};
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x1>;
+			next-level-cache = <&L1_1>;
+
+			L1_1: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x2>;
+			next-level-cache = <&L1_2>;
+
+			L1_2: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x3>;
+			next-level-cache = <&L1_3>;
+
+			L1_3: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			next-level-cache = <&L1_4>;
+
+			L1_4: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+
+			L2_1: l2-cache {
+				compatible = "arm,arch-cache";
+			};
+		};
+
+		cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			next-level-cache = <&L1_5>;
+
+			L1_5: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+
+		cpu at 102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x102>;
+			next-level-cache = <&L1_6>;
+
+			L1_6: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+
+		cpu at 103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x103>;
+			next-level-cache = <&L1_7>;
+
+			L1_7: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+	};
+
+[1] ARM Architecture Reference Manuals
+    http://infocenter.arm.com/help/index.jsp
+
+[2] ePAPR standard
+    https://www.power.org/documentation/epapr-version-1-1/
+
+[3] Kernel documentation - power domain bindings
+    Documentation/devicetree/bindings/power/power_domain.txt
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-03-18 11:28 ` Lorenzo Pieralisi
@ 2014-03-18 11:28   ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-18 11:28 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
	Lorenzo Pieralisi, Russell King, Sebastian Capella,
	Nicolas Pitre, Daniel Lezcano, linux-arm-kernel, Grant Likely,
	Dave Martin, Charles Garcia Tobin, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Vincent Guittot, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd, Amit Kucheria

ARM based platforms implement a variety of power management schemes that
allow processors to enter idle states at run-time.
The parameters defining these idle states vary on a per-platform basis forcing
the OS to hardcode the state parameters in platform specific static tables
whose size grows as the number of platforms supported in the kernel increases
and hampers device drivers standardization.

Therefore, this patch aims at standardizing idle state device tree bindings for
ARM platforms. Bindings define idle state parameters inclusive of entry methods
and state latencies, to allow operating systems to retrieve the configuration
entries from the device tree and initialize the related power management
drivers, paving the way for common code in the kernel to deal with idle
states and removing the need for static data in current and previous kernel
versions.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/cpus.txt     |  18 +
 .../devicetree/bindings/arm/idle-states.txt        | 771 +++++++++++++++++++++
 2 files changed, 789 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 9130435..79a1d9b 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -191,6 +191,19 @@ nodes to be present and contain the properties described below.
 			  property identifying a 64-bit zero-initialised
 			  memory location.
 
+	- cpu-idle-states
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition:
+			# List of phandles to idle state nodes supported
+			  by this cpu [1].
+
+	- power-domain
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition: A phandle and power domain specifier as defined by
+			    bindings of power domain specified by [2].
+
 Example 1 (dual-cluster big.LITTLE system 32-bit):
 
 	cpus {
@@ -382,3 +395,8 @@ cpus {
 		cpu-release-addr = <0 0x20000000>;
 	};
 };
+
+[1] ARM Linux kernel documentation - idle states bindings
+    Documentation/devicetree/bindings/arm/idle-states.txt
+[2] Kernel documentation - power domain bindings
+    Documentation/devicetree/bindings/power/power_domain.txt
diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt
new file mode 100644
index 0000000..fee176d
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/idle-states.txt
@@ -0,0 +1,771 @@
+==========================================
+ARM idle states binding description
+==========================================
+
+==========================================
+1 - Introduction
+==========================================
+
+ARM systems contain HW capable of managing power consumption dynamically,
+where cores can be put in different low-power states (ranging from simple
+wfi to power gating) according to OSPM policies. The CPU states representing
+the range of dynamic idle states that a processor can enter at run-time, can be
+specified through device tree bindings representing the parameters required
+to enter/exit specific idle states on a given processor.
+
+According to the Server Base System Architecture document (SBSA, [4]), the
+power states an ARM CPU can be put into are identified by the following list:
+
+- Running
+- Idle_standby
+- Idle_retention
+- Sleep
+- Off
+
+The power states described in the SBSA document define the basic CPU states on
+top of which ARM platforms implement power management schemes that allow an OS
+PM implementation to put the processor in different idle states (which include
+states listed above; "off" state is not an idle state since it does not have
+wake-up capabilities, hence it is not considered in this document).
+
+Idle state parameters (eg entry latency) are platform specific and need to be
+characterized with bindings that provide the required information to OSPM
+code so that it can build the required tables and use them at runtime.
+
+The device tree binding definition for ARM idle states is the subject of this
+document.
+
+===========================================
+2 - idle-states node
+===========================================
+
+ARM processor idle states are defined within the idle-states node, which is
+a direct child of the cpus node and provides a container where the processor
+idle states, defined as device tree nodes, are listed.
+
+- idle-states node
+
+	Usage: Optional - On ARM systems, is a container of processor idle
+			  states nodes. If the system does not provide CPU
+			  power management capabilities or the processor just
+			  supports idle_standby an idle-states node is not
+			  required.
+
+	Description: idle-states node is a container node, where its
+		     subnodes describe the CPU idle states.
+
+	Node name must be "idle-states".
+
+	The idle-states node's parent node must be the cpus node.
+
+	The idle-states node's child nodes can be:
+
+	- one or more state nodes
+
+	Any other configuration is considered invalid.
+
+	An idle-states node defines the following properties:
+
+	- entry-method
+		Usage: Required
+		Value type: <stringlist>
+		Definition: Describes the method by which a CPU enters the
+			    idle states. This property is required and must be
+			    one of:
+
+			    - "arm,psci"
+			      ARM PSCI firmware interface [3].
+
+			    - "[vendor],[method]"
+			      An implementation dependent string with
+			      format "vendor,method", where vendor is a string
+			      denoting the name of the manufacturer and
+			      method is a string specifying the mechanism
+			      used to enter the idle state.
+
+The nodes describing the idle states (state) can only be defined within the
+idle-states node.
+
+Any other configuration is consider invalid and therefore must be ignored.
+
+===========================================
+3 - state node
+===========================================
+
+A state node represents an idle state description and must be defined as
+follows:
+
+- state node
+
+	Description: must be child of either the idle-states node or
+		     a state node.
+
+	The state node name shall follow standard device tree naming
+	rules ([6], 2.2.1 "Node names"), in particular state nodes which
+	are siblings within a single common parent must be given a unique name.
+
+	The idle state entered by executing the wfi instruction (idle_standby
+	SBSA,[4][5]) is considered standard on all ARM platforms and therefore
+	must not be listed.
+
+	A state node can contain state child nodes. A state node with
+	children represents a hierarchical state, which is a superset of
+	the child states.
+
+	A state node defines the following properties:
+
+	- compatible
+		Usage: Required
+		Value type: <stringlist>
+		Definition: Must be "arm,idle-state".
+
+	- index
+		Usage: Required
+		Value type: <u32>
+		Definition: It represents the idle state index.
+			    The index must be given an increasing
+			    value = {0, 1, ....}, starting from 0, with higher
+			    values implying less power consumption.
+			    Indices must be unique as seen from a cpu
+			    perspective, ie phandles in the cpu nodes [1]
+			    cpu-idle-states array property are not allowed to
+			    point at idle state nodes having the same index
+			    value.
+
+	- logic-state-retained
+		Usage: See definition
+		Value type: <none>
+		Definition: if present logic is retained on state entry,
+			    otherwise it is lost.
+
+	- cache-state-retained
+		Usage: See definition
+		Value type: <none>
+		Definition: if present cache memory is retained on state entry,
+			    otherwise it is lost.
+
+	- entry-method-param
+		Usage: See definition.
+		Value type: <u32>
+		Definition: Depends on the idle-states node entry-method
+			    property value. Refer to the entry-method bindings
+			    for this property value definition.
+
+	- entry-latency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing worst case latency
+			    in microseconds required to enter the idle state.
+
+	- exit-latency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing worst case latency
+			    in microseconds required to exit the idle state.
+
+	- min-residency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing time in microseconds
+			    required for the CPU to be in the idle state to
+			    guarantee power savings maximization.
+
+	- power-domains
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition: List of phandle and power domain specifiers ([2])
+			    describing the power domains that are affected by
+			    the idle state entry. All devices whose
+			    power-domains property contains entries referring
+			    to one of the power domains listed in this
+			    property are affected by the idle state entry.
+
+===========================================
+4 - Examples
+===========================================
+
+Example 1 (ARM 64-bit, 16-cpu system):
+
+pd_clusters: power-domain-clusters@80002000 {
+	compatible = "arm,power-controller";
+	reg = <0x0 0x80002000 0x0 0x1000>;
+	#power-domain-cells = <1>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	pd_cores: power-domain-cores@80000000 {
+		compatible = "arm,power-controller";
+		reg = <0x0 0x80000000 0x0 0x1000>;
+		#power-domain-cells = <1>;
+	};
+};
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <2>;
+
+	idle-states {
+		entry-method = "arm,psci-cpu-suspend";
+
+		CLUSTER_RETENTION_0: cluster-retention-0 {
+			compatible = "arm,idle-state";
+			index = <2>;
+			logic-state-retained;
+			cache-state-retained;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <50>;
+			exit-latency-us = <100>;
+			min-residency-us = <250>;
+			power-domains = <&pd_clusters 0>;
+			CPU_RETENTION_0_0: cpu-retention-0 {
+				compatible = "arm,idle-state";
+				index = <0>;
+				cache-state-retained;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <20>;
+				exit-latency-us = <40>;
+				min-residency-us = <30>;
+				power-domains = <&pd_cores 0>,
+						<&pd_cores 1>,
+						<&pd_cores 2>,
+						<&pd_cores 3>,
+						<&pd_cores 4>,
+						<&pd_cores 5>,
+						<&pd_cores 6>,
+						<&pd_cores 7>;
+			};
+		};
+
+		CLUSTER_SLEEP_0: cluster-sleep-0 {
+			compatible = "arm,idle-state";
+			index = <3>;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <600>;
+			exit-latency-us = <1100>;
+			min-residency-us = <2700>;
+			power-domains = <&pd_clusters 0>;
+			CPU_SLEEP_0_0: cpu-sleep-0 {
+				/* cpu sleep */
+				compatible = "arm,idle-state";
+				index = <1>;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <250>;
+				exit-latency-us = <500>;
+				min-residency-us = <350>;
+				power-domains = <&pd_cores 0>,
+						<&pd_cores 1>,
+						<&pd_cores 2>,
+						<&pd_cores 3>,
+						<&pd_cores 4>,
+						<&pd_cores 5>,
+						<&pd_cores 6>,
+						<&pd_cores 7>;
+			};
+		};
+		CLUSTER_RETENTION_1: cluster-retention-1 {
+			compatible = "arm,idle-state";
+			index = <2>;
+			logic-state-retained;
+			cache-state-retained;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <50>;
+			exit-latency-us = <100>;
+			min-residency-us = <270>;
+			power-domains = <&pd_clusters 1>;
+			CPU_RETENTION_1_0: cpu-retention-0 {
+				compatible = "arm,idle-state";
+				index = <0>;
+				cache-state-retained;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <20>;
+				exit-latency-us = <40>;
+				min-residency-us = <30>;
+				power-domains = <&pd_cores 8>,
+						<&pd_cores 9>,
+						<&pd_cores 10>,
+						<&pd_cores 11>,
+						<&pd_cores 12>,
+						<&pd_cores 13>,
+						<&pd_cores 14>,
+						<&pd_cores 15>;
+			};
+		};
+
+		CLUSTER_SLEEP_1: cluster-sleep-1 {
+			compatible = "arm,idle-state";
+			index = <3>;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <500>;
+			exit-latency-us = <1200>;
+			min-residency-us = <3500>;
+			power-domains = <&pd_clusters 1>;
+			CPU_SLEEP_1_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				index = <1>;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <70>;
+				exit-latency-us = <100>;
+				min-residency-us = <100>;
+				power-domains = <&pd_cores 8>,
+						<&pd_cores 9>,
+						<&pd_cores 10>,
+						<&pd_cores 11>,
+						<&pd_cores 12>,
+						<&pd_cores 13>,
+						<&pd_cores 14>,
+						<&pd_cores 15>;
+			};
+		};
+	};
+
+	CPU0: cpu@0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x0>;
+		enable-method = "psci";
+		next-level-cache = <&L1_0>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_0: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 0>;
+		};
+		L2_0: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 0>;
+		};
+	};
+
+	CPU1: cpu@1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x1>;
+		enable-method = "psci";
+		next-level-cache = <&L1_1>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_1: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 1>;
+		};
+	};
+
+	CPU2: cpu@100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_2>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_2: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 2>;
+		};
+	};
+
+	CPU3: cpu@101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_3>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_3: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 3>;
+		};
+	};
+
+	CPU4: cpu@10000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10000>;
+		enable-method = "psci";
+		next-level-cache = <&L1_4>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_4: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 4>;
+		};
+	};
+
+	CPU5: cpu@10001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10001>;
+		enable-method = "psci";
+		next-level-cache = <&L1_5>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_5: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 5>;
+		};
+	};
+
+	CPU6: cpu@10100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_6>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_6: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 6>;
+		};
+	};
+
+	CPU7: cpu@10101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_7>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_7: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 7>;
+		};
+	};
+
+	CPU8: cpu@100000000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x0>;
+		enable-method = "psci";
+		next-level-cache = <&L1_8>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_8: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 8>;
+		};
+		L2_1: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 1>;
+		};
+	};
+
+	CPU9: cpu@100000001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x1>;
+		enable-method = "psci";
+		next-level-cache = <&L1_9>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_9: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 9>;
+		};
+	};
+
+	CPU10: cpu@100000100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_10>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_10: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 10>;
+		};
+	};
+
+	CPU11: cpu@100000101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_11>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_11: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 11>;
+		};
+	};
+
+	CPU12: cpu@100010000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10000>;
+		enable-method = "psci";
+		next-level-cache = <&L1_12>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_12: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 12>;
+		};
+	};
+
+	CPU13: cpu@100010001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10001>;
+		enable-method = "psci";
+		next-level-cache = <&L1_13>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_13: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 13>;
+		};
+	};
+
+	CPU14: cpu@100010100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_14>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_14: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 14>;
+		};
+	};
+
+	CPU15: cpu@100010101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_15>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_15: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 15>;
+		};
+	};
+};
+
+Example 2 (ARM 32-bit, 8-cpu system, two clusters):
+
+pd_clusters: power-domain-clusters@80002000 {
+	compatible = "arm,power-controller";
+	reg = <0x80002000 0x1000>;
+	#power-domain-cells = <1>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	pd_cores: power-domain-cores@80000000 {
+		compatible = "arm,power-controller";
+		reg = <0x80000000 0x1000>;
+		#power-domain-cells = <1>;
+	};
+};
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <1>;
+
+	idle-states {
+		entry-method = "arm,psci-cpu-suspend";
+
+		CLUSTER_SLEEP_0: cluster-sleep-0 {
+			compatible = "arm,idle-state";
+			index = <1>;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <1000>;
+			exit-latency-us = <1500>;
+			min-residency-us = <1500>;
+			power-domains = <&pd_clusters 0>;
+			CPU_SLEEP_0_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				index = <0>;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <400>;
+				exit-latency-us = <500>;
+				min-residency-us = <300>;
+				power-domains = <&pd_cores 0>,
+						<&pd_cores 1>,
+						<&pd_cores 2>,
+						<&pd_cores 3>;
+			};
+		};
+
+		CLUSTER_SLEEP_1: cluster-sleep-1 {
+			compatible = "arm,idle-state";
+			index = <1>;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <800>;
+			exit-latency-us = <2000>;
+			min-residency-us = <6500>;
+			power-domains = <&pd_clusters 1>;
+			CPU_SLEEP_1_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				index = <0>;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <300>;
+				exit-latency-us = <500>;
+				min-residency-us = <500>;
+				power-domains = <&pd_cores 4>,
+						<&pd_cores 5>,
+						<&pd_cores 6>,
+						<&pd_cores 7>;
+			};
+		};
+	};
+
+	CPU0: cpu@0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x0>;
+		next-level-cache = <&L1_0>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+		L1_0: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 0>;
+		};
+		L2_0: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 0>;
+		};
+	};
+
+	CPU1: cpu@1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x1>;
+		next-level-cache = <&L1_1>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+		L1_1: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 1>;
+		};
+	};
+
+	CPU2: cpu@2 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x2>;
+		next-level-cache = <&L1_2>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+		L1_2: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 2>;
+		};
+	};
+
+	CPU3: cpu@3 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x3>;
+		next-level-cache = <&L1_3>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+		L1_3: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 3>;
+		};
+	};
+
+	CPU4: cpu@100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x100>;
+		next-level-cache = <&L1_4>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+		L1_4: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 4>;
+		};
+		L2_1: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 1>;
+		};
+	};
+
+	CPU5: cpu@101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x101>;
+		next-level-cache = <&L1_5>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+		L1_5: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 5>;
+		};
+	};
+
+	CPU6: cpu@102 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x102>;
+		next-level-cache = <&L1_6>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+		L1_6: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 6>;
+		};
+	};
+
+	CPU7: cpu@103 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x103>;
+		next-level-cache = <&L1_7>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+		L1_7: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 7>;
+		};
+	};
+};
+
+===========================================
+4 - References
+===========================================
+
+[1] ARM Linux Kernel documentation - CPUs bindings
+    Documentation/devicetree/bindings/arm/cpus.txt
+
+[2] ARM Linux Kernel documentation - power domain bindings
+    Documentation/devicetree/bindings/power/power_domain.txt
+
+[3] ARM Linux Kernel documentation - PSCI bindings
+    Documentation/devicetree/bindings/arm/psci.txt
+
+[4] ARM Server Base System Architecture (SBSA)
+    http://infocenter.arm.com/help/index.jsp
+
+[5] ARM Architecture Reference Manuals
+    http://infocenter.arm.com/help/index.jsp
+
+[6] ePAPR standard
+    https://www.power.org/documentation/epapr-version-1-1/
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-03-18 11:28   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-03-18 11:28 UTC (permalink / raw)
  To: linux-arm-kernel

ARM based platforms implement a variety of power management schemes that
allow processors to enter idle states at run-time.
The parameters defining these idle states vary on a per-platform basis forcing
the OS to hardcode the state parameters in platform specific static tables
whose size grows as the number of platforms supported in the kernel increases
and hampers device drivers standardization.

Therefore, this patch aims at standardizing idle state device tree bindings for
ARM platforms. Bindings define idle state parameters inclusive of entry methods
and state latencies, to allow operating systems to retrieve the configuration
entries from the device tree and initialize the related power management
drivers, paving the way for common code in the kernel to deal with idle
states and removing the need for static data in current and previous kernel
versions.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/cpus.txt     |  18 +
 .../devicetree/bindings/arm/idle-states.txt        | 771 +++++++++++++++++++++
 2 files changed, 789 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 9130435..79a1d9b 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -191,6 +191,19 @@ nodes to be present and contain the properties described below.
 			  property identifying a 64-bit zero-initialised
 			  memory location.
 
+	- cpu-idle-states
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition:
+			# List of phandles to idle state nodes supported
+			  by this cpu [1].
+
+	- power-domain
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition: A phandle and power domain specifier as defined by
+			    bindings of power domain specified by [2].
+
 Example 1 (dual-cluster big.LITTLE system 32-bit):
 
 	cpus {
@@ -382,3 +395,8 @@ cpus {
 		cpu-release-addr = <0 0x20000000>;
 	};
 };
+
+[1] ARM Linux kernel documentation - idle states bindings
+    Documentation/devicetree/bindings/arm/idle-states.txt
+[2] Kernel documentation - power domain bindings
+    Documentation/devicetree/bindings/power/power_domain.txt
diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt
new file mode 100644
index 0000000..fee176d
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/idle-states.txt
@@ -0,0 +1,771 @@
+==========================================
+ARM idle states binding description
+==========================================
+
+==========================================
+1 - Introduction
+==========================================
+
+ARM systems contain HW capable of managing power consumption dynamically,
+where cores can be put in different low-power states (ranging from simple
+wfi to power gating) according to OSPM policies. The CPU states representing
+the range of dynamic idle states that a processor can enter at run-time, can be
+specified through device tree bindings representing the parameters required
+to enter/exit specific idle states on a given processor.
+
+According to the Server Base System Architecture document (SBSA, [4]), the
+power states an ARM CPU can be put into are identified by the following list:
+
+- Running
+- Idle_standby
+- Idle_retention
+- Sleep
+- Off
+
+The power states described in the SBSA document define the basic CPU states on
+top of which ARM platforms implement power management schemes that allow an OS
+PM implementation to put the processor in different idle states (which include
+states listed above; "off" state is not an idle state since it does not have
+wake-up capabilities, hence it is not considered in this document).
+
+Idle state parameters (eg entry latency) are platform specific and need to be
+characterized with bindings that provide the required information to OSPM
+code so that it can build the required tables and use them at runtime.
+
+The device tree binding definition for ARM idle states is the subject of this
+document.
+
+===========================================
+2 - idle-states node
+===========================================
+
+ARM processor idle states are defined within the idle-states node, which is
+a direct child of the cpus node and provides a container where the processor
+idle states, defined as device tree nodes, are listed.
+
+- idle-states node
+
+	Usage: Optional - On ARM systems, is a container of processor idle
+			  states nodes. If the system does not provide CPU
+			  power management capabilities or the processor just
+			  supports idle_standby an idle-states node is not
+			  required.
+
+	Description: idle-states node is a container node, where its
+		     subnodes describe the CPU idle states.
+
+	Node name must be "idle-states".
+
+	The idle-states node's parent node must be the cpus node.
+
+	The idle-states node's child nodes can be:
+
+	- one or more state nodes
+
+	Any other configuration is considered invalid.
+
+	An idle-states node defines the following properties:
+
+	- entry-method
+		Usage: Required
+		Value type: <stringlist>
+		Definition: Describes the method by which a CPU enters the
+			    idle states. This property is required and must be
+			    one of:
+
+			    - "arm,psci"
+			      ARM PSCI firmware interface [3].
+
+			    - "[vendor],[method]"
+			      An implementation dependent string with
+			      format "vendor,method", where vendor is a string
+			      denoting the name of the manufacturer and
+			      method is a string specifying the mechanism
+			      used to enter the idle state.
+
+The nodes describing the idle states (state) can only be defined within the
+idle-states node.
+
+Any other configuration is consider invalid and therefore must be ignored.
+
+===========================================
+3 - state node
+===========================================
+
+A state node represents an idle state description and must be defined as
+follows:
+
+- state node
+
+	Description: must be child of either the idle-states node or
+		     a state node.
+
+	The state node name shall follow standard device tree naming
+	rules ([6], 2.2.1 "Node names"), in particular state nodes which
+	are siblings within a single common parent must be given a unique name.
+
+	The idle state entered by executing the wfi instruction (idle_standby
+	SBSA,[4][5]) is considered standard on all ARM platforms and therefore
+	must not be listed.
+
+	A state node can contain state child nodes. A state node with
+	children represents a hierarchical state, which is a superset of
+	the child states.
+
+	A state node defines the following properties:
+
+	- compatible
+		Usage: Required
+		Value type: <stringlist>
+		Definition: Must be "arm,idle-state".
+
+	- index
+		Usage: Required
+		Value type: <u32>
+		Definition: It represents the idle state index.
+			    The index must be given an increasing
+			    value = {0, 1, ....}, starting from 0, with higher
+			    values implying less power consumption.
+			    Indices must be unique as seen from a cpu
+			    perspective, ie phandles in the cpu nodes [1]
+			    cpu-idle-states array property are not allowed to
+			    point at idle state nodes having the same index
+			    value.
+
+	- logic-state-retained
+		Usage: See definition
+		Value type: <none>
+		Definition: if present logic is retained on state entry,
+			    otherwise it is lost.
+
+	- cache-state-retained
+		Usage: See definition
+		Value type: <none>
+		Definition: if present cache memory is retained on state entry,
+			    otherwise it is lost.
+
+	- entry-method-param
+		Usage: See definition.
+		Value type: <u32>
+		Definition: Depends on the idle-states node entry-method
+			    property value. Refer to the entry-method bindings
+			    for this property value definition.
+
+	- entry-latency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing worst case latency
+			    in microseconds required to enter the idle state.
+
+	- exit-latency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing worst case latency
+			    in microseconds required to exit the idle state.
+
+	- min-residency-us
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: u32 value representing time in microseconds
+			    required for the CPU to be in the idle state to
+			    guarantee power savings maximization.
+
+	- power-domains
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition: List of phandle and power domain specifiers ([2])
+			    describing the power domains that are affected by
+			    the idle state entry. All devices whose
+			    power-domains property contains entries referring
+			    to one of the power domains listed in this
+			    property are affected by the idle state entry.
+
+===========================================
+4 - Examples
+===========================================
+
+Example 1 (ARM 64-bit, 16-cpu system):
+
+pd_clusters: power-domain-clusters at 80002000 {
+	compatible = "arm,power-controller";
+	reg = <0x0 0x80002000 0x0 0x1000>;
+	#power-domain-cells = <1>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	pd_cores: power-domain-cores at 80000000 {
+		compatible = "arm,power-controller";
+		reg = <0x0 0x80000000 0x0 0x1000>;
+		#power-domain-cells = <1>;
+	};
+};
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <2>;
+
+	idle-states {
+		entry-method = "arm,psci-cpu-suspend";
+
+		CLUSTER_RETENTION_0: cluster-retention-0 {
+			compatible = "arm,idle-state";
+			index = <2>;
+			logic-state-retained;
+			cache-state-retained;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <50>;
+			exit-latency-us = <100>;
+			min-residency-us = <250>;
+			power-domains = <&pd_clusters 0>;
+			CPU_RETENTION_0_0: cpu-retention-0 {
+				compatible = "arm,idle-state";
+				index = <0>;
+				cache-state-retained;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <20>;
+				exit-latency-us = <40>;
+				min-residency-us = <30>;
+				power-domains = <&pd_cores 0>,
+						<&pd_cores 1>,
+						<&pd_cores 2>,
+						<&pd_cores 3>,
+						<&pd_cores 4>,
+						<&pd_cores 5>,
+						<&pd_cores 6>,
+						<&pd_cores 7>;
+			};
+		};
+
+		CLUSTER_SLEEP_0: cluster-sleep-0 {
+			compatible = "arm,idle-state";
+			index = <3>;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <600>;
+			exit-latency-us = <1100>;
+			min-residency-us = <2700>;
+			power-domains = <&pd_clusters 0>;
+			CPU_SLEEP_0_0: cpu-sleep-0 {
+				/* cpu sleep */
+				compatible = "arm,idle-state";
+				index = <1>;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <250>;
+				exit-latency-us = <500>;
+				min-residency-us = <350>;
+				power-domains = <&pd_cores 0>,
+						<&pd_cores 1>,
+						<&pd_cores 2>,
+						<&pd_cores 3>,
+						<&pd_cores 4>,
+						<&pd_cores 5>,
+						<&pd_cores 6>,
+						<&pd_cores 7>;
+			};
+		};
+		CLUSTER_RETENTION_1: cluster-retention-1 {
+			compatible = "arm,idle-state";
+			index = <2>;
+			logic-state-retained;
+			cache-state-retained;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <50>;
+			exit-latency-us = <100>;
+			min-residency-us = <270>;
+			power-domains = <&pd_clusters 1>;
+			CPU_RETENTION_1_0: cpu-retention-0 {
+				compatible = "arm,idle-state";
+				index = <0>;
+				cache-state-retained;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <20>;
+				exit-latency-us = <40>;
+				min-residency-us = <30>;
+				power-domains = <&pd_cores 8>,
+						<&pd_cores 9>,
+						<&pd_cores 10>,
+						<&pd_cores 11>,
+						<&pd_cores 12>,
+						<&pd_cores 13>,
+						<&pd_cores 14>,
+						<&pd_cores 15>;
+			};
+		};
+
+		CLUSTER_SLEEP_1: cluster-sleep-1 {
+			compatible = "arm,idle-state";
+			index = <3>;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <500>;
+			exit-latency-us = <1200>;
+			min-residency-us = <3500>;
+			power-domains = <&pd_clusters 1>;
+			CPU_SLEEP_1_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				index = <1>;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <70>;
+				exit-latency-us = <100>;
+				min-residency-us = <100>;
+				power-domains = <&pd_cores 8>,
+						<&pd_cores 9>,
+						<&pd_cores 10>,
+						<&pd_cores 11>,
+						<&pd_cores 12>,
+						<&pd_cores 13>,
+						<&pd_cores 14>,
+						<&pd_cores 15>;
+			};
+		};
+	};
+
+	CPU0: cpu at 0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x0>;
+		enable-method = "psci";
+		next-level-cache = <&L1_0>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_0: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 0>;
+		};
+		L2_0: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 0>;
+		};
+	};
+
+	CPU1: cpu at 1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x1>;
+		enable-method = "psci";
+		next-level-cache = <&L1_1>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_1: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 1>;
+		};
+	};
+
+	CPU2: cpu at 100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_2>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_2: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 2>;
+		};
+	};
+
+	CPU3: cpu at 101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_3>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_3: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 3>;
+		};
+	};
+
+	CPU4: cpu at 10000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10000>;
+		enable-method = "psci";
+		next-level-cache = <&L1_4>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_4: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 4>;
+		};
+	};
+
+	CPU5: cpu at 10001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10001>;
+		enable-method = "psci";
+		next-level-cache = <&L1_5>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_5: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 5>;
+		};
+	};
+
+	CPU6: cpu at 10100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_6>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_6: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 6>;
+		};
+	};
+
+	CPU7: cpu at 10101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_7>;
+		cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
+				   &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
+		L1_7: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 7>;
+		};
+	};
+
+	CPU8: cpu at 100000000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x0>;
+		enable-method = "psci";
+		next-level-cache = <&L1_8>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_8: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 8>;
+		};
+		L2_1: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 1>;
+		};
+	};
+
+	CPU9: cpu at 100000001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x1>;
+		enable-method = "psci";
+		next-level-cache = <&L1_9>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_9: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 9>;
+		};
+	};
+
+	CPU10: cpu at 100000100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_10>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_10: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 10>;
+		};
+	};
+
+	CPU11: cpu at 100000101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_11>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_11: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 11>;
+		};
+	};
+
+	CPU12: cpu at 100010000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10000>;
+		enable-method = "psci";
+		next-level-cache = <&L1_12>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_12: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 12>;
+		};
+	};
+
+	CPU13: cpu at 100010001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10001>;
+		enable-method = "psci";
+		next-level-cache = <&L1_13>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_13: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 13>;
+		};
+	};
+
+	CPU14: cpu at 100010100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_14>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_14: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 14>;
+		};
+	};
+
+	CPU15: cpu at 100010101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_15>;
+		cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
+				   &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
+		L1_15: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 15>;
+		};
+	};
+};
+
+Example 2 (ARM 32-bit, 8-cpu system, two clusters):
+
+pd_clusters: power-domain-clusters at 80002000 {
+	compatible = "arm,power-controller";
+	reg = <0x80002000 0x1000>;
+	#power-domain-cells = <1>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	pd_cores: power-domain-cores at 80000000 {
+		compatible = "arm,power-controller";
+		reg = <0x80000000 0x1000>;
+		#power-domain-cells = <1>;
+	};
+};
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <1>;
+
+	idle-states {
+		entry-method = "arm,psci-cpu-suspend";
+
+		CLUSTER_SLEEP_0: cluster-sleep-0 {
+			compatible = "arm,idle-state";
+			index = <1>;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <1000>;
+			exit-latency-us = <1500>;
+			min-residency-us = <1500>;
+			power-domains = <&pd_clusters 0>;
+			CPU_SLEEP_0_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				index = <0>;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <400>;
+				exit-latency-us = <500>;
+				min-residency-us = <300>;
+				power-domains = <&pd_cores 0>,
+						<&pd_cores 1>,
+						<&pd_cores 2>,
+						<&pd_cores 3>;
+			};
+		};
+
+		CLUSTER_SLEEP_1: cluster-sleep-1 {
+			compatible = "arm,idle-state";
+			index = <1>;
+			entry-method-param = <0x1010000>;
+			entry-latency-us = <800>;
+			exit-latency-us = <2000>;
+			min-residency-us = <6500>;
+			power-domains = <&pd_clusters 1>;
+			CPU_SLEEP_1_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				index = <0>;
+				entry-method-param = <0x0010000>;
+				entry-latency-us = <300>;
+				exit-latency-us = <500>;
+				min-residency-us = <500>;
+				power-domains = <&pd_cores 4>,
+						<&pd_cores 5>,
+						<&pd_cores 6>,
+						<&pd_cores 7>;
+			};
+		};
+	};
+
+	CPU0: cpu at 0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x0>;
+		next-level-cache = <&L1_0>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+		L1_0: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 0>;
+		};
+		L2_0: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 0>;
+		};
+	};
+
+	CPU1: cpu at 1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x1>;
+		next-level-cache = <&L1_1>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+		L1_1: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 1>;
+		};
+	};
+
+	CPU2: cpu at 2 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x2>;
+		next-level-cache = <&L1_2>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+		L1_2: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 2>;
+		};
+	};
+
+	CPU3: cpu at 3 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x3>;
+		next-level-cache = <&L1_3>;
+		cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
+		L1_3: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 3>;
+		};
+	};
+
+	CPU4: cpu at 100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x100>;
+		next-level-cache = <&L1_4>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+		L1_4: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 4>;
+		};
+		L2_1: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 1>;
+		};
+	};
+
+	CPU5: cpu at 101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x101>;
+		next-level-cache = <&L1_5>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+		L1_5: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 5>;
+		};
+	};
+
+	CPU6: cpu at 102 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x102>;
+		next-level-cache = <&L1_6>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+		L1_6: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 6>;
+		};
+	};
+
+	CPU7: cpu at 103 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x103>;
+		next-level-cache = <&L1_7>;
+		cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
+		L1_7: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 7>;
+		};
+	};
+};
+
+===========================================
+4 - References
+===========================================
+
+[1] ARM Linux Kernel documentation - CPUs bindings
+    Documentation/devicetree/bindings/arm/cpus.txt
+
+[2] ARM Linux Kernel documentation - power domain bindings
+    Documentation/devicetree/bindings/power/power_domain.txt
+
+[3] ARM Linux Kernel documentation - PSCI bindings
+    Documentation/devicetree/bindings/arm/psci.txt
+
+[4] ARM Server Base System Architecture (SBSA)
+    http://infocenter.arm.com/help/index.jsp
+
+[5] ARM Architecture Reference Manuals
+    http://infocenter.arm.com/help/index.jsp
+
+[6] ePAPR standard
+    https://www.power.org/documentation/epapr-version-1-1/
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-03-18 11:28   ` Lorenzo Pieralisi
@ 2014-04-04 15:56     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-04 15:56 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
	Russell King, Sebastian Capella, Nicolas Pitre, Daniel Lezcano,
	linux-arm-kernel, grant.likely, Dave P Martin,
	Charles Garcia-Tobin, Kevin Hilman, linux-pm, Kumar Gala,
	Rob Herring, Vincent Guittot, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd

[replying to self, since I have a query]

[...]

> +===========================================
> +4 - Examples
> +===========================================
> +
> +Example 1 (ARM 64-bit, 16-cpu system):
> +
> +pd_clusters: power-domain-clusters@80002000 {
> +       compatible = "arm,power-controller";
> +       reg = <0x0 0x80002000 0x0 0x1000>;
> +       #power-domain-cells = <1>;
> +       #address-cells = <2>;
> +       #size-cells = <2>;
> +
> +       pd_cores: power-domain-cores@80000000 {
> +               compatible = "arm,power-controller";
> +               reg = <0x0 0x80000000 0x0 0x1000>;
> +               #power-domain-cells = <1>;
> +       };
> +};
> +
> +cpus {
> +       #size-cells = <0>;
> +       #address-cells = <2>;
> +
> +       idle-states {
> +               entry-method = "arm,psci-cpu-suspend";
> +
> +               CLUSTER_RETENTION_0: cluster-retention-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <2>;
> +                       logic-state-retained;
> +                       cache-state-retained;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <50>;
> +                       exit-latency-us = <100>;
> +                       min-residency-us = <250>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_RETENTION_0_0: cpu-retention-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               cache-state-retained;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <20>;
> +                               exit-latency-us = <40>;
> +                               min-residency-us = <30>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>,
> +                                               <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };
> +
> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <3>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <600>;
> +                       exit-latency-us = <1100>;
> +                       min-residency-us = <2700>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> +                               /* cpu sleep */
> +                               compatible = "arm,idle-state";
> +                               index = <1>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <250>;
> +                               exit-latency-us = <500>;
> +                               min-residency-us = <350>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>,
> +                                               <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };

I noticed while developing the CPUidle generic driver, that by using this
representation I might end up requiring duplicated states.

For instance, a cluster-retention state and a cluster-sleep state might
want to have cpu-sleep state as substate, and this would require an
idle state node duplication.

I think it is better to have a single flat (and ordered...that would
kill two birds with one stone) list of nodes in the idle-states node and
every state might have a list of phandles to subnodes (substates), something
like the following example.

This simplifies parsing  and I think it solves the last issue I
came across (the need for duplicate states - in the bindings below,
CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
CLUSTER_SLEEP_0, through phandles).

Thoughts very appreciated, thanks.

Lorenzo

idle-states {
       entry-method = "arm,psci-cpu-suspend";

	CPU_RETENTION_0: cpu-retention-0 {
		       compatible = "arm,idle-state";
		       cache-state-retained;
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <20>;
		       exit-latency-us = <40>;
		       min-residency-us = <30>;
		       power-domains = <&pd_cores 0>,
				       <&pd_cores 1>,
				       <&pd_cores 2>,
				       <&pd_cores 3>,
	};

	CPU_SLEEP_0: cpu-sleep-0 {
		       /* cpu sleep */
		       compatible = "arm,idle-state";
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <250>;
		       exit-latency-us = <500>;
		       min-residency-us = <350>;
		       power-domains = <&pd_cores 0>,
				       <&pd_cores 1>,
				       <&pd_cores 2>,
				       <&pd_cores 3>,
	};

	CPU_SLEEP_1: cpu-sleep-1 {
		       /* cpu sleep */
		       compatible = "arm,idle-state";
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <250>;
		       exit-latency-us = <500>;
		       min-residency-us = <350>;
				       <&pd_cores 4>,
				       <&pd_cores 5>,
				       <&pd_cores 6>,
				       <&pd_cores 7>;
	};

	CLUSTER_RETENTION_0: cluster-retention-0 {
	       compatible = "arm,idle-state";
	       logic-state-retained;
	       cache-state-retained;
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <50>;
	       exit-latency-us = <800>;
	       min-residency-us = <2400>;
	       power-domains = <&pd_clusters 0>;
	       substates = <&CPU_SLEEP_0>;
	};

	CLUSTER_SLEEP_0: cluster-sleep-0 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <600>;
	       exit-latency-us = <1100>;
	       min-residency-us = <2700>;
	       power-domains = <&pd_clusters 0>;
	       substates = <&CPU_SLEEP_0>;
	};

	CLUSTER_SLEEP_1: cluster-sleep-1 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <600>;
	       exit-latency-us = <1100>;
	       min-residency-us = <2700>;
	       power-domains = <&pd_clusters 1>;
	       substates = <&CPU_SLEEP_1>;
	};

	SYSTEM_SLEEP_0: system-sleep-0 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x2010000>;
	       entry-latency-us = <6000>;
	       exit-latency-us = <10000>;
	       min-residency-us = <30000>;
	       power-domains = <&pd_system 0>;
	       substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
	};
};

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-04 15:56     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-04 15:56 UTC (permalink / raw)
  To: linux-arm-kernel

[replying to self, since I have a query]

[...]

> +===========================================
> +4 - Examples
> +===========================================
> +
> +Example 1 (ARM 64-bit, 16-cpu system):
> +
> +pd_clusters: power-domain-clusters at 80002000 {
> +       compatible = "arm,power-controller";
> +       reg = <0x0 0x80002000 0x0 0x1000>;
> +       #power-domain-cells = <1>;
> +       #address-cells = <2>;
> +       #size-cells = <2>;
> +
> +       pd_cores: power-domain-cores at 80000000 {
> +               compatible = "arm,power-controller";
> +               reg = <0x0 0x80000000 0x0 0x1000>;
> +               #power-domain-cells = <1>;
> +       };
> +};
> +
> +cpus {
> +       #size-cells = <0>;
> +       #address-cells = <2>;
> +
> +       idle-states {
> +               entry-method = "arm,psci-cpu-suspend";
> +
> +               CLUSTER_RETENTION_0: cluster-retention-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <2>;
> +                       logic-state-retained;
> +                       cache-state-retained;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <50>;
> +                       exit-latency-us = <100>;
> +                       min-residency-us = <250>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_RETENTION_0_0: cpu-retention-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               cache-state-retained;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <20>;
> +                               exit-latency-us = <40>;
> +                               min-residency-us = <30>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>,
> +                                               <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };
> +
> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <3>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <600>;
> +                       exit-latency-us = <1100>;
> +                       min-residency-us = <2700>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> +                               /* cpu sleep */
> +                               compatible = "arm,idle-state";
> +                               index = <1>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <250>;
> +                               exit-latency-us = <500>;
> +                               min-residency-us = <350>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>,
> +                                               <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };

I noticed while developing the CPUidle generic driver, that by using this
representation I might end up requiring duplicated states.

For instance, a cluster-retention state and a cluster-sleep state might
want to have cpu-sleep state as substate, and this would require an
idle state node duplication.

I think it is better to have a single flat (and ordered...that would
kill two birds with one stone) list of nodes in the idle-states node and
every state might have a list of phandles to subnodes (substates), something
like the following example.

This simplifies parsing  and I think it solves the last issue I
came across (the need for duplicate states - in the bindings below,
CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
CLUSTER_SLEEP_0, through phandles).

Thoughts very appreciated, thanks.

Lorenzo

idle-states {
       entry-method = "arm,psci-cpu-suspend";

	CPU_RETENTION_0: cpu-retention-0 {
		       compatible = "arm,idle-state";
		       cache-state-retained;
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <20>;
		       exit-latency-us = <40>;
		       min-residency-us = <30>;
		       power-domains = <&pd_cores 0>,
				       <&pd_cores 1>,
				       <&pd_cores 2>,
				       <&pd_cores 3>,
	};

	CPU_SLEEP_0: cpu-sleep-0 {
		       /* cpu sleep */
		       compatible = "arm,idle-state";
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <250>;
		       exit-latency-us = <500>;
		       min-residency-us = <350>;
		       power-domains = <&pd_cores 0>,
				       <&pd_cores 1>,
				       <&pd_cores 2>,
				       <&pd_cores 3>,
	};

	CPU_SLEEP_1: cpu-sleep-1 {
		       /* cpu sleep */
		       compatible = "arm,idle-state";
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <250>;
		       exit-latency-us = <500>;
		       min-residency-us = <350>;
				       <&pd_cores 4>,
				       <&pd_cores 5>,
				       <&pd_cores 6>,
				       <&pd_cores 7>;
	};

	CLUSTER_RETENTION_0: cluster-retention-0 {
	       compatible = "arm,idle-state";
	       logic-state-retained;
	       cache-state-retained;
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <50>;
	       exit-latency-us = <800>;
	       min-residency-us = <2400>;
	       power-domains = <&pd_clusters 0>;
	       substates = <&CPU_SLEEP_0>;
	};

	CLUSTER_SLEEP_0: cluster-sleep-0 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <600>;
	       exit-latency-us = <1100>;
	       min-residency-us = <2700>;
	       power-domains = <&pd_clusters 0>;
	       substates = <&CPU_SLEEP_0>;
	};

	CLUSTER_SLEEP_1: cluster-sleep-1 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <600>;
	       exit-latency-us = <1100>;
	       min-residency-us = <2700>;
	       power-domains = <&pd_clusters 1>;
	       substates = <&CPU_SLEEP_1>;
	};

	SYSTEM_SLEEP_0: system-sleep-0 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x2010000>;
	       entry-latency-us = <6000>;
	       exit-latency-us = <10000>;
	       min-residency-us = <30000>;
	       power-domains = <&pd_system 0>;
	       substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
	};
};

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-04-04 15:56     ` Lorenzo Pieralisi
@ 2014-04-04 22:01       ` Sebastian Capella
  -1 siblings, 0 replies; 26+ messages in thread
From: Sebastian Capella @ 2014-04-04 22:01 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
	Russell King, Nicolas Pitre, Daniel Lezcano, linux-arm-kernel,
	grant.likely, Dave P Martin, Charles Garcia-Tobin, devicetree,
	Kevin Hilman, linux-pm, Kumar Gala, Rob Herring, Vincent Guittot,
	Antti Miettinen, Peter De Schrijver, Stephen Boyd, Amit

Hi Lorenzo,

I like this :)

I was going to suggest linking the tree upside down (starting with the
leaves such that walking the list takes you back to the root node
(system sleep), but I don't think it matters as long as the
relationship is established (which this does).  I tend to think of
these states in that order, starting from the leaf(shallowest idle
state) and working back to the root(system sleep) since it provides a
simple linear view of the sleep states from the cpu perspective, yet
keeps the heirarchy.

Sebastian

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-04 22:01       ` Sebastian Capella
  0 siblings, 0 replies; 26+ messages in thread
From: Sebastian Capella @ 2014-04-04 22:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lorenzo,

I like this :)

I was going to suggest linking the tree upside down (starting with the
leaves such that walking the list takes you back to the root node
(system sleep), but I don't think it matters as long as the
relationship is established (which this does).  I tend to think of
these states in that order, starting from the leaf(shallowest idle
state) and working back to the root(system sleep) since it provides a
simple linear view of the sleep states from the cpu perspective, yet
keeps the heirarchy.

Sebastian

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-04-04 22:01       ` Sebastian Capella
@ 2014-04-07 11:52         ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-07 11:52 UTC (permalink / raw)
  To: Sebastian Capella
  Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
	Russell King, Nicolas Pitre, Daniel Lezcano, linux-arm-kernel,
	grant.likely, Dave P Martin, Charles Garcia-Tobin, devicetree,
	Kevin Hilman, linux-pm, Kumar Gala, Rob Herring, Vincent Guittot,
	Antti Miettinen, Peter De Schrijver, Stephen Boyd, Amit

On Fri, Apr 04, 2014 at 11:01:06PM +0100, Sebastian Capella wrote:
> Hi Lorenzo,
> 
> I like this :)
> 
> I was going to suggest linking the tree upside down (starting with the
> leaves such that walking the list takes you back to the root node
> (system sleep), but I don't think it matters as long as the
> relationship is established (which this does).  I tend to think of
> these states in that order, starting from the leaf(shallowest idle
> state) and working back to the root(system sleep) since it provides a
> simple linear view of the sleep states from the cpu perspective, yet
> keeps the heirarchy.

Copied the bindings here for the sake of this discussion.

I think it is more natural to have deeper states pointing at their
subnodes instead of the other way around. When you are in eg
cluster-sleep-0 below you want to check what subnodes the current
state "contains", not the other way around (eg in cluster-sleep-0, by
checking all subnodes we can span the power-domains and check what needs
saving/restoring).

It would be awkward to be forced to check, for every state, all state
nodes pointing at it, the dependency is better defined in the state
itself.

Furthermore, this approch gets closer to what we will do with ACPI,
where state nodes will become ACPI objects returned by AML methods (which
avoids duplication, as phandles do).

Should I go for this approach and leave the ordering to the DT idle state
nodes flat declaration order ? Or we still want to define a property for
that ?

Please, let me know what you think, thanks.

Lorenzo

idle-states {
       entry-method = "arm,psci-cpu-suspend";

	CPU_RETENTION_0: cpu-retention-0 {
		       compatible = "arm,idle-state";
		       cache-state-retained;
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <20>;
		       exit-latency-us = <40>;
		       min-residency-us = <30>;
		       power-domains = <&pd_cores 0>,
				       <&pd_cores 1>,
				       <&pd_cores 2>,
				       <&pd_cores 3>,
	};

	CPU_SLEEP_0: cpu-sleep-0 {
		       /* cpu sleep */
		       compatible = "arm,idle-state";
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <250>;
		       exit-latency-us = <500>;
		       min-residency-us = <350>;
		       power-domains = <&pd_cores 0>,
				       <&pd_cores 1>,
				       <&pd_cores 2>,
				       <&pd_cores 3>,
	};

	CPU_SLEEP_1: cpu-sleep-1 {
		       /* cpu sleep */
		       compatible = "arm,idle-state";
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <250>;
		       exit-latency-us = <500>;
		       min-residency-us = <350>;
				       <&pd_cores 4>,
				       <&pd_cores 5>,
				       <&pd_cores 6>,
				       <&pd_cores 7>;
	};

	CLUSTER_RETENTION_0: cluster-retention-0 {
	       compatible = "arm,idle-state";
	       logic-state-retained;
	       cache-state-retained;
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <50>;
	       exit-latency-us = <800>;
	       min-residency-us = <2400>;
	       power-domains = <&pd_clusters 0>;
	       substates = <&CPU_SLEEP_0>;
	};

	CLUSTER_SLEEP_0: cluster-sleep-0 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <600>;
	       exit-latency-us = <1100>;
	       min-residency-us = <2700>;
	       power-domains = <&pd_clusters 0>;
	       substates = <&CPU_SLEEP_0>;
	};

	CLUSTER_SLEEP_1: cluster-sleep-1 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <600>;
	       exit-latency-us = <1100>;
	       min-residency-us = <2700>;
	       power-domains = <&pd_clusters 1>;
	       substates = <&CPU_SLEEP_1>;
	};

	SYSTEM_SLEEP_0: system-sleep-0 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x2010000>;
	       entry-latency-us = <6000>;
	       exit-latency-us = <10000>;
	       min-residency-us = <30000>;
	       power-domains = <&pd_system 0>;
	       substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
	};
};

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-07 11:52         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-07 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 04, 2014 at 11:01:06PM +0100, Sebastian Capella wrote:
> Hi Lorenzo,
> 
> I like this :)
> 
> I was going to suggest linking the tree upside down (starting with the
> leaves such that walking the list takes you back to the root node
> (system sleep), but I don't think it matters as long as the
> relationship is established (which this does).  I tend to think of
> these states in that order, starting from the leaf(shallowest idle
> state) and working back to the root(system sleep) since it provides a
> simple linear view of the sleep states from the cpu perspective, yet
> keeps the heirarchy.

Copied the bindings here for the sake of this discussion.

I think it is more natural to have deeper states pointing at their
subnodes instead of the other way around. When you are in eg
cluster-sleep-0 below you want to check what subnodes the current
state "contains", not the other way around (eg in cluster-sleep-0, by
checking all subnodes we can span the power-domains and check what needs
saving/restoring).

It would be awkward to be forced to check, for every state, all state
nodes pointing at it, the dependency is better defined in the state
itself.

Furthermore, this approch gets closer to what we will do with ACPI,
where state nodes will become ACPI objects returned by AML methods (which
avoids duplication, as phandles do).

Should I go for this approach and leave the ordering to the DT idle state
nodes flat declaration order ? Or we still want to define a property for
that ?

Please, let me know what you think, thanks.

Lorenzo

idle-states {
       entry-method = "arm,psci-cpu-suspend";

	CPU_RETENTION_0: cpu-retention-0 {
		       compatible = "arm,idle-state";
		       cache-state-retained;
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <20>;
		       exit-latency-us = <40>;
		       min-residency-us = <30>;
		       power-domains = <&pd_cores 0>,
				       <&pd_cores 1>,
				       <&pd_cores 2>,
				       <&pd_cores 3>,
	};

	CPU_SLEEP_0: cpu-sleep-0 {
		       /* cpu sleep */
		       compatible = "arm,idle-state";
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <250>;
		       exit-latency-us = <500>;
		       min-residency-us = <350>;
		       power-domains = <&pd_cores 0>,
				       <&pd_cores 1>,
				       <&pd_cores 2>,
				       <&pd_cores 3>,
	};

	CPU_SLEEP_1: cpu-sleep-1 {
		       /* cpu sleep */
		       compatible = "arm,idle-state";
		       entry-method-param = <0x0010000>;
		       entry-latency-us = <250>;
		       exit-latency-us = <500>;
		       min-residency-us = <350>;
				       <&pd_cores 4>,
				       <&pd_cores 5>,
				       <&pd_cores 6>,
				       <&pd_cores 7>;
	};

	CLUSTER_RETENTION_0: cluster-retention-0 {
	       compatible = "arm,idle-state";
	       logic-state-retained;
	       cache-state-retained;
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <50>;
	       exit-latency-us = <800>;
	       min-residency-us = <2400>;
	       power-domains = <&pd_clusters 0>;
	       substates = <&CPU_SLEEP_0>;
	};

	CLUSTER_SLEEP_0: cluster-sleep-0 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <600>;
	       exit-latency-us = <1100>;
	       min-residency-us = <2700>;
	       power-domains = <&pd_clusters 0>;
	       substates = <&CPU_SLEEP_0>;
	};

	CLUSTER_SLEEP_1: cluster-sleep-1 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x1010000>;
	       entry-latency-us = <600>;
	       exit-latency-us = <1100>;
	       min-residency-us = <2700>;
	       power-domains = <&pd_clusters 1>;
	       substates = <&CPU_SLEEP_1>;
	};

	SYSTEM_SLEEP_0: system-sleep-0 {
	       compatible = "arm,idle-state";
	       entry-method-param = <0x2010000>;
	       entry-latency-us = <6000>;
	       exit-latency-us = <10000>;
	       min-residency-us = <30000>;
	       power-domains = <&pd_system 0>;
	       substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
	};
};

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-04-04 15:56     ` Lorenzo Pieralisi
@ 2014-04-07 12:25       ` Vincent Guittot
  -1 siblings, 0 replies; 26+ messages in thread
From: Vincent Guittot @ 2014-04-07 12:25 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Mark Rutland, Tomasz Figa, Mark Hambleton, Russell King,
	Sebastian Capella, Nicolas Pitre, Daniel Lezcano,
	linux-arm-kernel, grant.likely, Dave P Martin,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Mike Turquette, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd

On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> [replying to self, since I have a query]
>
> [...]
>
>> +===========================================
>> +4 - Examples
>> +===========================================
>> +
>> +Example 1 (ARM 64-bit, 16-cpu system):
>> +
>> +pd_clusters: power-domain-clusters@80002000 {
>> +       compatible = "arm,power-controller";
>> +       reg = <0x0 0x80002000 0x0 0x1000>;
>> +       #power-domain-cells = <1>;
>> +       #address-cells = <2>;
>> +       #size-cells = <2>;
>> +
>> +       pd_cores: power-domain-cores@80000000 {
>> +               compatible = "arm,power-controller";
>> +               reg = <0x0 0x80000000 0x0 0x1000>;
>> +               #power-domain-cells = <1>;
>> +       };
>> +};
>> +
>> +cpus {
>> +       #size-cells = <0>;
>> +       #address-cells = <2>;
>> +
>> +       idle-states {
>> +               entry-method = "arm,psci-cpu-suspend";
>> +
>> +               CLUSTER_RETENTION_0: cluster-retention-0 {
>> +                       compatible = "arm,idle-state";
>> +                       index = <2>;
>> +                       logic-state-retained;
>> +                       cache-state-retained;
>> +                       entry-method-param = <0x1010000>;
>> +                       entry-latency-us = <50>;
>> +                       exit-latency-us = <100>;
>> +                       min-residency-us = <250>;
>> +                       power-domains = <&pd_clusters 0>;
>> +                       CPU_RETENTION_0_0: cpu-retention-0 {
>> +                               compatible = "arm,idle-state";
>> +                               index = <0>;
>> +                               cache-state-retained;
>> +                               entry-method-param = <0x0010000>;
>> +                               entry-latency-us = <20>;
>> +                               exit-latency-us = <40>;
>> +                               min-residency-us = <30>;
>> +                               power-domains = <&pd_cores 0>,
>> +                                               <&pd_cores 1>,
>> +                                               <&pd_cores 2>,
>> +                                               <&pd_cores 3>,
>> +                                               <&pd_cores 4>,
>> +                                               <&pd_cores 5>,
>> +                                               <&pd_cores 6>,
>> +                                               <&pd_cores 7>;
>> +                       };
>> +               };
>> +
>> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
>> +                       compatible = "arm,idle-state";
>> +                       index = <3>;
>> +                       entry-method-param = <0x1010000>;
>> +                       entry-latency-us = <600>;
>> +                       exit-latency-us = <1100>;
>> +                       min-residency-us = <2700>;
>> +                       power-domains = <&pd_clusters 0>;
>> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
>> +                               /* cpu sleep */
>> +                               compatible = "arm,idle-state";
>> +                               index = <1>;
>> +                               entry-method-param = <0x0010000>;
>> +                               entry-latency-us = <250>;
>> +                               exit-latency-us = <500>;
>> +                               min-residency-us = <350>;
>> +                               power-domains = <&pd_cores 0>,
>> +                                               <&pd_cores 1>,
>> +                                               <&pd_cores 2>,
>> +                                               <&pd_cores 3>,
>> +                                               <&pd_cores 4>,
>> +                                               <&pd_cores 5>,
>> +                                               <&pd_cores 6>,
>> +                                               <&pd_cores 7>;
>> +                       };
>> +               };
>
> I noticed while developing the CPUidle generic driver, that by using this
> representation I might end up requiring duplicated states.
>
> For instance, a cluster-retention state and a cluster-sleep state might
> want to have cpu-sleep state as substate, and this would require an
> idle state node duplication.
>
> I think it is better to have a single flat (and ordered...that would
> kill two birds with one stone) list of nodes in the idle-states node and
> every state might have a list of phandles to subnodes (substates), something
> like the following example.
>
> This simplifies parsing  and I think it solves the last issue I
> came across (the need for duplicate states - in the bindings below,
> CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
> CLUSTER_SLEEP_0, through phandles).

Hi Lorenzo,

You explanation above has triggered a question. You writes:
CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
can have some in sleep mode and other in retention of course)
I'm wondering how this OR  will be described.

Then, IMHO, the flat description below is clearer and remove the
duplicated description that you mention previously

Regards,
Vincent

>
> Thoughts very appreciated, thanks.
>
> Lorenzo
>
> idle-states {
>        entry-method = "arm,psci-cpu-suspend";
>
>         CPU_RETENTION_0: cpu-retention-0 {
>                        compatible = "arm,idle-state";
>                        cache-state-retained;
>                        entry-method-param = <0x0010000>;
>                        entry-latency-us = <20>;
>                        exit-latency-us = <40>;
>                        min-residency-us = <30>;
>                        power-domains = <&pd_cores 0>,
>                                        <&pd_cores 1>,
>                                        <&pd_cores 2>,
>                                        <&pd_cores 3>,
>         };
>
>         CPU_SLEEP_0: cpu-sleep-0 {
>                        /* cpu sleep */
>                        compatible = "arm,idle-state";
>                        entry-method-param = <0x0010000>;
>                        entry-latency-us = <250>;
>                        exit-latency-us = <500>;
>                        min-residency-us = <350>;
>                        power-domains = <&pd_cores 0>,
>                                        <&pd_cores 1>,
>                                        <&pd_cores 2>,
>                                        <&pd_cores 3>,
>         };
>
>         CPU_SLEEP_1: cpu-sleep-1 {
>                        /* cpu sleep */
>                        compatible = "arm,idle-state";
>                        entry-method-param = <0x0010000>;
>                        entry-latency-us = <250>;
>                        exit-latency-us = <500>;
>                        min-residency-us = <350>;
>                                        <&pd_cores 4>,
>                                        <&pd_cores 5>,
>                                        <&pd_cores 6>,
>                                        <&pd_cores 7>;
>         };
>
>         CLUSTER_RETENTION_0: cluster-retention-0 {
>                compatible = "arm,idle-state";
>                logic-state-retained;
>                cache-state-retained;
>                entry-method-param = <0x1010000>;
>                entry-latency-us = <50>;
>                exit-latency-us = <800>;
>                min-residency-us = <2400>;
>                power-domains = <&pd_clusters 0>;
>                substates = <&CPU_SLEEP_0>;
>         };
>
>         CLUSTER_SLEEP_0: cluster-sleep-0 {
>                compatible = "arm,idle-state";
>                entry-method-param = <0x1010000>;
>                entry-latency-us = <600>;
>                exit-latency-us = <1100>;
>                min-residency-us = <2700>;
>                power-domains = <&pd_clusters 0>;
>                substates = <&CPU_SLEEP_0>;
>         };
>
>         CLUSTER_SLEEP_1: cluster-sleep-1 {
>                compatible = "arm,idle-state";
>                entry-method-param = <0x1010000>;
>                entry-latency-us = <600>;
>                exit-latency-us = <1100>;
>                min-residency-us = <2700>;
>                power-domains = <&pd_clusters 1>;
>                substates = <&CPU_SLEEP_1>;
>         };
>
>         SYSTEM_SLEEP_0: system-sleep-0 {
>                compatible = "arm,idle-state";
>                entry-method-param = <0x2010000>;
>                entry-latency-us = <6000>;
>                exit-latency-us = <10000>;
>                min-residency-us = <30000>;
>                power-domains = <&pd_system 0>;
>                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
>         };
> };
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-07 12:25       ` Vincent Guittot
  0 siblings, 0 replies; 26+ messages in thread
From: Vincent Guittot @ 2014-04-07 12:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> [replying to self, since I have a query]
>
> [...]
>
>> +===========================================
>> +4 - Examples
>> +===========================================
>> +
>> +Example 1 (ARM 64-bit, 16-cpu system):
>> +
>> +pd_clusters: power-domain-clusters at 80002000 {
>> +       compatible = "arm,power-controller";
>> +       reg = <0x0 0x80002000 0x0 0x1000>;
>> +       #power-domain-cells = <1>;
>> +       #address-cells = <2>;
>> +       #size-cells = <2>;
>> +
>> +       pd_cores: power-domain-cores at 80000000 {
>> +               compatible = "arm,power-controller";
>> +               reg = <0x0 0x80000000 0x0 0x1000>;
>> +               #power-domain-cells = <1>;
>> +       };
>> +};
>> +
>> +cpus {
>> +       #size-cells = <0>;
>> +       #address-cells = <2>;
>> +
>> +       idle-states {
>> +               entry-method = "arm,psci-cpu-suspend";
>> +
>> +               CLUSTER_RETENTION_0: cluster-retention-0 {
>> +                       compatible = "arm,idle-state";
>> +                       index = <2>;
>> +                       logic-state-retained;
>> +                       cache-state-retained;
>> +                       entry-method-param = <0x1010000>;
>> +                       entry-latency-us = <50>;
>> +                       exit-latency-us = <100>;
>> +                       min-residency-us = <250>;
>> +                       power-domains = <&pd_clusters 0>;
>> +                       CPU_RETENTION_0_0: cpu-retention-0 {
>> +                               compatible = "arm,idle-state";
>> +                               index = <0>;
>> +                               cache-state-retained;
>> +                               entry-method-param = <0x0010000>;
>> +                               entry-latency-us = <20>;
>> +                               exit-latency-us = <40>;
>> +                               min-residency-us = <30>;
>> +                               power-domains = <&pd_cores 0>,
>> +                                               <&pd_cores 1>,
>> +                                               <&pd_cores 2>,
>> +                                               <&pd_cores 3>,
>> +                                               <&pd_cores 4>,
>> +                                               <&pd_cores 5>,
>> +                                               <&pd_cores 6>,
>> +                                               <&pd_cores 7>;
>> +                       };
>> +               };
>> +
>> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
>> +                       compatible = "arm,idle-state";
>> +                       index = <3>;
>> +                       entry-method-param = <0x1010000>;
>> +                       entry-latency-us = <600>;
>> +                       exit-latency-us = <1100>;
>> +                       min-residency-us = <2700>;
>> +                       power-domains = <&pd_clusters 0>;
>> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
>> +                               /* cpu sleep */
>> +                               compatible = "arm,idle-state";
>> +                               index = <1>;
>> +                               entry-method-param = <0x0010000>;
>> +                               entry-latency-us = <250>;
>> +                               exit-latency-us = <500>;
>> +                               min-residency-us = <350>;
>> +                               power-domains = <&pd_cores 0>,
>> +                                               <&pd_cores 1>,
>> +                                               <&pd_cores 2>,
>> +                                               <&pd_cores 3>,
>> +                                               <&pd_cores 4>,
>> +                                               <&pd_cores 5>,
>> +                                               <&pd_cores 6>,
>> +                                               <&pd_cores 7>;
>> +                       };
>> +               };
>
> I noticed while developing the CPUidle generic driver, that by using this
> representation I might end up requiring duplicated states.
>
> For instance, a cluster-retention state and a cluster-sleep state might
> want to have cpu-sleep state as substate, and this would require an
> idle state node duplication.
>
> I think it is better to have a single flat (and ordered...that would
> kill two birds with one stone) list of nodes in the idle-states node and
> every state might have a list of phandles to subnodes (substates), something
> like the following example.
>
> This simplifies parsing  and I think it solves the last issue I
> came across (the need for duplicate states - in the bindings below,
> CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
> CLUSTER_SLEEP_0, through phandles).

Hi Lorenzo,

You explanation above has triggered a question. You writes:
CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
can have some in sleep mode and other in retention of course)
I'm wondering how this OR  will be described.

Then, IMHO, the flat description below is clearer and remove the
duplicated description that you mention previously

Regards,
Vincent

>
> Thoughts very appreciated, thanks.
>
> Lorenzo
>
> idle-states {
>        entry-method = "arm,psci-cpu-suspend";
>
>         CPU_RETENTION_0: cpu-retention-0 {
>                        compatible = "arm,idle-state";
>                        cache-state-retained;
>                        entry-method-param = <0x0010000>;
>                        entry-latency-us = <20>;
>                        exit-latency-us = <40>;
>                        min-residency-us = <30>;
>                        power-domains = <&pd_cores 0>,
>                                        <&pd_cores 1>,
>                                        <&pd_cores 2>,
>                                        <&pd_cores 3>,
>         };
>
>         CPU_SLEEP_0: cpu-sleep-0 {
>                        /* cpu sleep */
>                        compatible = "arm,idle-state";
>                        entry-method-param = <0x0010000>;
>                        entry-latency-us = <250>;
>                        exit-latency-us = <500>;
>                        min-residency-us = <350>;
>                        power-domains = <&pd_cores 0>,
>                                        <&pd_cores 1>,
>                                        <&pd_cores 2>,
>                                        <&pd_cores 3>,
>         };
>
>         CPU_SLEEP_1: cpu-sleep-1 {
>                        /* cpu sleep */
>                        compatible = "arm,idle-state";
>                        entry-method-param = <0x0010000>;
>                        entry-latency-us = <250>;
>                        exit-latency-us = <500>;
>                        min-residency-us = <350>;
>                                        <&pd_cores 4>,
>                                        <&pd_cores 5>,
>                                        <&pd_cores 6>,
>                                        <&pd_cores 7>;
>         };
>
>         CLUSTER_RETENTION_0: cluster-retention-0 {
>                compatible = "arm,idle-state";
>                logic-state-retained;
>                cache-state-retained;
>                entry-method-param = <0x1010000>;
>                entry-latency-us = <50>;
>                exit-latency-us = <800>;
>                min-residency-us = <2400>;
>                power-domains = <&pd_clusters 0>;
>                substates = <&CPU_SLEEP_0>;
>         };
>
>         CLUSTER_SLEEP_0: cluster-sleep-0 {
>                compatible = "arm,idle-state";
>                entry-method-param = <0x1010000>;
>                entry-latency-us = <600>;
>                exit-latency-us = <1100>;
>                min-residency-us = <2700>;
>                power-domains = <&pd_clusters 0>;
>                substates = <&CPU_SLEEP_0>;
>         };
>
>         CLUSTER_SLEEP_1: cluster-sleep-1 {
>                compatible = "arm,idle-state";
>                entry-method-param = <0x1010000>;
>                entry-latency-us = <600>;
>                exit-latency-us = <1100>;
>                min-residency-us = <2700>;
>                power-domains = <&pd_clusters 1>;
>                substates = <&CPU_SLEEP_1>;
>         };
>
>         SYSTEM_SLEEP_0: system-sleep-0 {
>                compatible = "arm,idle-state";
>                entry-method-param = <0x2010000>;
>                entry-latency-us = <6000>;
>                exit-latency-us = <10000>;
>                min-residency-us = <30000>;
>                power-domains = <&pd_system 0>;
>                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
>         };
> };
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-04-07 12:25       ` Vincent Guittot
@ 2014-04-07 14:36         ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-07 14:36 UTC (permalink / raw)
  To: Vincent Guittot
  Cc: Mark Rutland, Tomasz Figa, Mark Hambleton, Russell King,
	Sebastian Capella, Nicolas Pitre, Daniel Lezcano,
	linux-arm-kernel, grant.likely, Dave P Martin,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Mike Turquette, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd

On Mon, Apr 07, 2014 at 01:25:17PM +0100, Vincent Guittot wrote:
> On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> > [replying to self, since I have a query]
> >
> > [...]
> >
> >> +===========================================
> >> +4 - Examples
> >> +===========================================
> >> +
> >> +Example 1 (ARM 64-bit, 16-cpu system):
> >> +
> >> +pd_clusters: power-domain-clusters@80002000 {
> >> +       compatible = "arm,power-controller";
> >> +       reg = <0x0 0x80002000 0x0 0x1000>;
> >> +       #power-domain-cells = <1>;
> >> +       #address-cells = <2>;
> >> +       #size-cells = <2>;
> >> +
> >> +       pd_cores: power-domain-cores@80000000 {
> >> +               compatible = "arm,power-controller";
> >> +               reg = <0x0 0x80000000 0x0 0x1000>;
> >> +               #power-domain-cells = <1>;
> >> +       };
> >> +};
> >> +
> >> +cpus {
> >> +       #size-cells = <0>;
> >> +       #address-cells = <2>;
> >> +
> >> +       idle-states {
> >> +               entry-method = "arm,psci-cpu-suspend";
> >> +
> >> +               CLUSTER_RETENTION_0: cluster-retention-0 {
> >> +                       compatible = "arm,idle-state";
> >> +                       index = <2>;
> >> +                       logic-state-retained;
> >> +                       cache-state-retained;
> >> +                       entry-method-param = <0x1010000>;
> >> +                       entry-latency-us = <50>;
> >> +                       exit-latency-us = <100>;
> >> +                       min-residency-us = <250>;
> >> +                       power-domains = <&pd_clusters 0>;
> >> +                       CPU_RETENTION_0_0: cpu-retention-0 {
> >> +                               compatible = "arm,idle-state";
> >> +                               index = <0>;
> >> +                               cache-state-retained;
> >> +                               entry-method-param = <0x0010000>;
> >> +                               entry-latency-us = <20>;
> >> +                               exit-latency-us = <40>;
> >> +                               min-residency-us = <30>;
> >> +                               power-domains = <&pd_cores 0>,
> >> +                                               <&pd_cores 1>,
> >> +                                               <&pd_cores 2>,
> >> +                                               <&pd_cores 3>,
> >> +                                               <&pd_cores 4>,
> >> +                                               <&pd_cores 5>,
> >> +                                               <&pd_cores 6>,
> >> +                                               <&pd_cores 7>;
> >> +                       };
> >> +               };
> >> +
> >> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> >> +                       compatible = "arm,idle-state";
> >> +                       index = <3>;
> >> +                       entry-method-param = <0x1010000>;
> >> +                       entry-latency-us = <600>;
> >> +                       exit-latency-us = <1100>;
> >> +                       min-residency-us = <2700>;
> >> +                       power-domains = <&pd_clusters 0>;
> >> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> >> +                               /* cpu sleep */
> >> +                               compatible = "arm,idle-state";
> >> +                               index = <1>;
> >> +                               entry-method-param = <0x0010000>;
> >> +                               entry-latency-us = <250>;
> >> +                               exit-latency-us = <500>;
> >> +                               min-residency-us = <350>;
> >> +                               power-domains = <&pd_cores 0>,
> >> +                                               <&pd_cores 1>,
> >> +                                               <&pd_cores 2>,
> >> +                                               <&pd_cores 3>,
> >> +                                               <&pd_cores 4>,
> >> +                                               <&pd_cores 5>,
> >> +                                               <&pd_cores 6>,
> >> +                                               <&pd_cores 7>;
> >> +                       };
> >> +               };
> >
> > I noticed while developing the CPUidle generic driver, that by using this
> > representation I might end up requiring duplicated states.
> >
> > For instance, a cluster-retention state and a cluster-sleep state might
> > want to have cpu-sleep state as substate, and this would require an
> > idle state node duplication.
> >
> > I think it is better to have a single flat (and ordered...that would
> > kill two birds with one stone) list of nodes in the idle-states node and
> > every state might have a list of phandles to subnodes (substates), something
> > like the following example.
> >
> > This simplifies parsing  and I think it solves the last issue I
> > came across (the need for duplicate states - in the bindings below,
> > CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
> > CLUSTER_SLEEP_0, through phandles).
> 
> Hi Lorenzo,
> 
> You explanation above has triggered a question. You writes:
> CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
> that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
> CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
> OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
> can have some in sleep mode and other in retention of course)
> I'm wondering how this OR  will be described.

We need another state (because that's what happens in HW right ?), so we
describe it (obviously having different latencies):


        CLUSTER_RETENTION_1: cluster-retention-1 {
                compatible = "arm,idle-state";
                logic-state-retained;
                cache-state-retained;
                entry-method-param = <0x1010000>;
                entry-latency-us = <50>;
                exit-latency-us = <700>;
                min-residency-us = <2000>;
                power-domains = <&pd_clusters 0>;
                substates = <&CPU_RETENTION_0>;
         };

Using phandles all state combinations are now possible, with no state
duplication.

State above is entered when all CPUs are in retention mode and thanks
to the phandle the kernel knows what has to be done as far as each
CPU is concerned. The beauty of this approach is that for every state,
it is well defined what has to be done for the respective power domain
(eg state above, cache is retained. All caches in <&pd_clusters 0> are
retained. Then we follow the substates, and take action according to
the substate propertes and respective power domain).

Does this make sense ? I can't find fault with this semantics, but
please let me know if you do.

Thank you !!
Lorenzo

> Then, IMHO, the flat description below is clearer and remove the
> duplicated description that you mention previously
> 
> Regards,
> Vincent
> 
> >
> > Thoughts very appreciated, thanks.
> >
> > Lorenzo
> >
> > idle-states {
> >        entry-method = "arm,psci-cpu-suspend";
> >
> >         CPU_RETENTION_0: cpu-retention-0 {
> >                        compatible = "arm,idle-state";
> >                        cache-state-retained;
> >                        entry-method-param = <0x0010000>;
> >                        entry-latency-us = <20>;
> >                        exit-latency-us = <40>;
> >                        min-residency-us = <30>;
> >                        power-domains = <&pd_cores 0>,
> >                                        <&pd_cores 1>,
> >                                        <&pd_cores 2>,
> >                                        <&pd_cores 3>,
> >         };
> >
> >         CPU_SLEEP_0: cpu-sleep-0 {
> >                        /* cpu sleep */
> >                        compatible = "arm,idle-state";
> >                        entry-method-param = <0x0010000>;
> >                        entry-latency-us = <250>;
> >                        exit-latency-us = <500>;
> >                        min-residency-us = <350>;
> >                        power-domains = <&pd_cores 0>,
> >                                        <&pd_cores 1>,
> >                                        <&pd_cores 2>,
> >                                        <&pd_cores 3>,
> >         };
> >
> >         CPU_SLEEP_1: cpu-sleep-1 {
> >                        /* cpu sleep */
> >                        compatible = "arm,idle-state";
> >                        entry-method-param = <0x0010000>;
> >                        entry-latency-us = <250>;
> >                        exit-latency-us = <500>;
> >                        min-residency-us = <350>;
> >                                        <&pd_cores 4>,
> >                                        <&pd_cores 5>,
> >                                        <&pd_cores 6>,
> >                                        <&pd_cores 7>;
> >         };
> >
> >         CLUSTER_RETENTION_0: cluster-retention-0 {
> >                compatible = "arm,idle-state";
> >                logic-state-retained;
> >                cache-state-retained;
> >                entry-method-param = <0x1010000>;
> >                entry-latency-us = <50>;
> >                exit-latency-us = <800>;
> >                min-residency-us = <2400>;
> >                power-domains = <&pd_clusters 0>;
> >                substates = <&CPU_SLEEP_0>;
> >         };
> >
> >         CLUSTER_SLEEP_0: cluster-sleep-0 {
> >                compatible = "arm,idle-state";
> >                entry-method-param = <0x1010000>;
> >                entry-latency-us = <600>;
> >                exit-latency-us = <1100>;
> >                min-residency-us = <2700>;
> >                power-domains = <&pd_clusters 0>;
> >                substates = <&CPU_SLEEP_0>;
> >         };
> >
> >         CLUSTER_SLEEP_1: cluster-sleep-1 {
> >                compatible = "arm,idle-state";
> >                entry-method-param = <0x1010000>;
> >                entry-latency-us = <600>;
> >                exit-latency-us = <1100>;
> >                min-residency-us = <2700>;
> >                power-domains = <&pd_clusters 1>;
> >                substates = <&CPU_SLEEP_1>;
> >         };
> >
> >         SYSTEM_SLEEP_0: system-sleep-0 {
> >                compatible = "arm,idle-state";
> >                entry-method-param = <0x2010000>;
> >                entry-latency-us = <6000>;
> >                exit-latency-us = <10000>;
> >                min-residency-us = <30000>;
> >                power-domains = <&pd_system 0>;
> >                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
> >         };
> > };
> >
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-07 14:36         ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-07 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 07, 2014 at 01:25:17PM +0100, Vincent Guittot wrote:
> On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> > [replying to self, since I have a query]
> >
> > [...]
> >
> >> +===========================================
> >> +4 - Examples
> >> +===========================================
> >> +
> >> +Example 1 (ARM 64-bit, 16-cpu system):
> >> +
> >> +pd_clusters: power-domain-clusters at 80002000 {
> >> +       compatible = "arm,power-controller";
> >> +       reg = <0x0 0x80002000 0x0 0x1000>;
> >> +       #power-domain-cells = <1>;
> >> +       #address-cells = <2>;
> >> +       #size-cells = <2>;
> >> +
> >> +       pd_cores: power-domain-cores at 80000000 {
> >> +               compatible = "arm,power-controller";
> >> +               reg = <0x0 0x80000000 0x0 0x1000>;
> >> +               #power-domain-cells = <1>;
> >> +       };
> >> +};
> >> +
> >> +cpus {
> >> +       #size-cells = <0>;
> >> +       #address-cells = <2>;
> >> +
> >> +       idle-states {
> >> +               entry-method = "arm,psci-cpu-suspend";
> >> +
> >> +               CLUSTER_RETENTION_0: cluster-retention-0 {
> >> +                       compatible = "arm,idle-state";
> >> +                       index = <2>;
> >> +                       logic-state-retained;
> >> +                       cache-state-retained;
> >> +                       entry-method-param = <0x1010000>;
> >> +                       entry-latency-us = <50>;
> >> +                       exit-latency-us = <100>;
> >> +                       min-residency-us = <250>;
> >> +                       power-domains = <&pd_clusters 0>;
> >> +                       CPU_RETENTION_0_0: cpu-retention-0 {
> >> +                               compatible = "arm,idle-state";
> >> +                               index = <0>;
> >> +                               cache-state-retained;
> >> +                               entry-method-param = <0x0010000>;
> >> +                               entry-latency-us = <20>;
> >> +                               exit-latency-us = <40>;
> >> +                               min-residency-us = <30>;
> >> +                               power-domains = <&pd_cores 0>,
> >> +                                               <&pd_cores 1>,
> >> +                                               <&pd_cores 2>,
> >> +                                               <&pd_cores 3>,
> >> +                                               <&pd_cores 4>,
> >> +                                               <&pd_cores 5>,
> >> +                                               <&pd_cores 6>,
> >> +                                               <&pd_cores 7>;
> >> +                       };
> >> +               };
> >> +
> >> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> >> +                       compatible = "arm,idle-state";
> >> +                       index = <3>;
> >> +                       entry-method-param = <0x1010000>;
> >> +                       entry-latency-us = <600>;
> >> +                       exit-latency-us = <1100>;
> >> +                       min-residency-us = <2700>;
> >> +                       power-domains = <&pd_clusters 0>;
> >> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> >> +                               /* cpu sleep */
> >> +                               compatible = "arm,idle-state";
> >> +                               index = <1>;
> >> +                               entry-method-param = <0x0010000>;
> >> +                               entry-latency-us = <250>;
> >> +                               exit-latency-us = <500>;
> >> +                               min-residency-us = <350>;
> >> +                               power-domains = <&pd_cores 0>,
> >> +                                               <&pd_cores 1>,
> >> +                                               <&pd_cores 2>,
> >> +                                               <&pd_cores 3>,
> >> +                                               <&pd_cores 4>,
> >> +                                               <&pd_cores 5>,
> >> +                                               <&pd_cores 6>,
> >> +                                               <&pd_cores 7>;
> >> +                       };
> >> +               };
> >
> > I noticed while developing the CPUidle generic driver, that by using this
> > representation I might end up requiring duplicated states.
> >
> > For instance, a cluster-retention state and a cluster-sleep state might
> > want to have cpu-sleep state as substate, and this would require an
> > idle state node duplication.
> >
> > I think it is better to have a single flat (and ordered...that would
> > kill two birds with one stone) list of nodes in the idle-states node and
> > every state might have a list of phandles to subnodes (substates), something
> > like the following example.
> >
> > This simplifies parsing  and I think it solves the last issue I
> > came across (the need for duplicate states - in the bindings below,
> > CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
> > CLUSTER_SLEEP_0, through phandles).
> 
> Hi Lorenzo,
> 
> You explanation above has triggered a question. You writes:
> CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
> that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
> CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
> OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
> can have some in sleep mode and other in retention of course)
> I'm wondering how this OR  will be described.

We need another state (because that's what happens in HW right ?), so we
describe it (obviously having different latencies):


        CLUSTER_RETENTION_1: cluster-retention-1 {
                compatible = "arm,idle-state";
                logic-state-retained;
                cache-state-retained;
                entry-method-param = <0x1010000>;
                entry-latency-us = <50>;
                exit-latency-us = <700>;
                min-residency-us = <2000>;
                power-domains = <&pd_clusters 0>;
                substates = <&CPU_RETENTION_0>;
         };

Using phandles all state combinations are now possible, with no state
duplication.

State above is entered when all CPUs are in retention mode and thanks
to the phandle the kernel knows what has to be done as far as each
CPU is concerned. The beauty of this approach is that for every state,
it is well defined what has to be done for the respective power domain
(eg state above, cache is retained. All caches in <&pd_clusters 0> are
retained. Then we follow the substates, and take action according to
the substate propertes and respective power domain).

Does this make sense ? I can't find fault with this semantics, but
please let me know if you do.

Thank you !!
Lorenzo

> Then, IMHO, the flat description below is clearer and remove the
> duplicated description that you mention previously
> 
> Regards,
> Vincent
> 
> >
> > Thoughts very appreciated, thanks.
> >
> > Lorenzo
> >
> > idle-states {
> >        entry-method = "arm,psci-cpu-suspend";
> >
> >         CPU_RETENTION_0: cpu-retention-0 {
> >                        compatible = "arm,idle-state";
> >                        cache-state-retained;
> >                        entry-method-param = <0x0010000>;
> >                        entry-latency-us = <20>;
> >                        exit-latency-us = <40>;
> >                        min-residency-us = <30>;
> >                        power-domains = <&pd_cores 0>,
> >                                        <&pd_cores 1>,
> >                                        <&pd_cores 2>,
> >                                        <&pd_cores 3>,
> >         };
> >
> >         CPU_SLEEP_0: cpu-sleep-0 {
> >                        /* cpu sleep */
> >                        compatible = "arm,idle-state";
> >                        entry-method-param = <0x0010000>;
> >                        entry-latency-us = <250>;
> >                        exit-latency-us = <500>;
> >                        min-residency-us = <350>;
> >                        power-domains = <&pd_cores 0>,
> >                                        <&pd_cores 1>,
> >                                        <&pd_cores 2>,
> >                                        <&pd_cores 3>,
> >         };
> >
> >         CPU_SLEEP_1: cpu-sleep-1 {
> >                        /* cpu sleep */
> >                        compatible = "arm,idle-state";
> >                        entry-method-param = <0x0010000>;
> >                        entry-latency-us = <250>;
> >                        exit-latency-us = <500>;
> >                        min-residency-us = <350>;
> >                                        <&pd_cores 4>,
> >                                        <&pd_cores 5>,
> >                                        <&pd_cores 6>,
> >                                        <&pd_cores 7>;
> >         };
> >
> >         CLUSTER_RETENTION_0: cluster-retention-0 {
> >                compatible = "arm,idle-state";
> >                logic-state-retained;
> >                cache-state-retained;
> >                entry-method-param = <0x1010000>;
> >                entry-latency-us = <50>;
> >                exit-latency-us = <800>;
> >                min-residency-us = <2400>;
> >                power-domains = <&pd_clusters 0>;
> >                substates = <&CPU_SLEEP_0>;
> >         };
> >
> >         CLUSTER_SLEEP_0: cluster-sleep-0 {
> >                compatible = "arm,idle-state";
> >                entry-method-param = <0x1010000>;
> >                entry-latency-us = <600>;
> >                exit-latency-us = <1100>;
> >                min-residency-us = <2700>;
> >                power-domains = <&pd_clusters 0>;
> >                substates = <&CPU_SLEEP_0>;
> >         };
> >
> >         CLUSTER_SLEEP_1: cluster-sleep-1 {
> >                compatible = "arm,idle-state";
> >                entry-method-param = <0x1010000>;
> >                entry-latency-us = <600>;
> >                exit-latency-us = <1100>;
> >                min-residency-us = <2700>;
> >                power-domains = <&pd_clusters 1>;
> >                substates = <&CPU_SLEEP_1>;
> >         };
> >
> >         SYSTEM_SLEEP_0: system-sleep-0 {
> >                compatible = "arm,idle-state";
> >                entry-method-param = <0x2010000>;
> >                entry-latency-us = <6000>;
> >                exit-latency-us = <10000>;
> >                min-residency-us = <30000>;
> >                power-domains = <&pd_system 0>;
> >                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
> >         };
> > };
> >
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-04-07 14:36         ` Lorenzo Pieralisi
@ 2014-04-07 15:34           ` Vincent Guittot
  -1 siblings, 0 replies; 26+ messages in thread
From: Vincent Guittot @ 2014-04-07 15:34 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Mark Rutland, Tomasz Figa, Mark Hambleton, Russell King,
	Sebastian Capella, Nicolas Pitre, Daniel Lezcano,
	linux-arm-kernel, grant.likely, Dave P Martin,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Mike Turquette, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd

On 7 April 2014 16:36, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Mon, Apr 07, 2014 at 01:25:17PM +0100, Vincent Guittot wrote:
>> On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> > [replying to self, since I have a query]
>> >
>> > [...]
>> >
>> >> +===========================================
>> >> +4 - Examples
>> >> +===========================================
>> >> +
>> >> +Example 1 (ARM 64-bit, 16-cpu system):
>> >> +
>> >> +pd_clusters: power-domain-clusters@80002000 {
>> >> +       compatible = "arm,power-controller";
>> >> +       reg = <0x0 0x80002000 0x0 0x1000>;
>> >> +       #power-domain-cells = <1>;
>> >> +       #address-cells = <2>;
>> >> +       #size-cells = <2>;
>> >> +
>> >> +       pd_cores: power-domain-cores@80000000 {
>> >> +               compatible = "arm,power-controller";
>> >> +               reg = <0x0 0x80000000 0x0 0x1000>;
>> >> +               #power-domain-cells = <1>;
>> >> +       };
>> >> +};
>> >> +
>> >> +cpus {
>> >> +       #size-cells = <0>;
>> >> +       #address-cells = <2>;
>> >> +
>> >> +       idle-states {
>> >> +               entry-method = "arm,psci-cpu-suspend";
>> >> +
>> >> +               CLUSTER_RETENTION_0: cluster-retention-0 {
>> >> +                       compatible = "arm,idle-state";
>> >> +                       index = <2>;
>> >> +                       logic-state-retained;
>> >> +                       cache-state-retained;
>> >> +                       entry-method-param = <0x1010000>;
>> >> +                       entry-latency-us = <50>;
>> >> +                       exit-latency-us = <100>;
>> >> +                       min-residency-us = <250>;
>> >> +                       power-domains = <&pd_clusters 0>;
>> >> +                       CPU_RETENTION_0_0: cpu-retention-0 {
>> >> +                               compatible = "arm,idle-state";
>> >> +                               index = <0>;
>> >> +                               cache-state-retained;
>> >> +                               entry-method-param = <0x0010000>;
>> >> +                               entry-latency-us = <20>;
>> >> +                               exit-latency-us = <40>;
>> >> +                               min-residency-us = <30>;
>> >> +                               power-domains = <&pd_cores 0>,
>> >> +                                               <&pd_cores 1>,
>> >> +                                               <&pd_cores 2>,
>> >> +                                               <&pd_cores 3>,
>> >> +                                               <&pd_cores 4>,
>> >> +                                               <&pd_cores 5>,
>> >> +                                               <&pd_cores 6>,
>> >> +                                               <&pd_cores 7>;
>> >> +                       };
>> >> +               };
>> >> +
>> >> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
>> >> +                       compatible = "arm,idle-state";
>> >> +                       index = <3>;
>> >> +                       entry-method-param = <0x1010000>;
>> >> +                       entry-latency-us = <600>;
>> >> +                       exit-latency-us = <1100>;
>> >> +                       min-residency-us = <2700>;
>> >> +                       power-domains = <&pd_clusters 0>;
>> >> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
>> >> +                               /* cpu sleep */
>> >> +                               compatible = "arm,idle-state";
>> >> +                               index = <1>;
>> >> +                               entry-method-param = <0x0010000>;
>> >> +                               entry-latency-us = <250>;
>> >> +                               exit-latency-us = <500>;
>> >> +                               min-residency-us = <350>;
>> >> +                               power-domains = <&pd_cores 0>,
>> >> +                                               <&pd_cores 1>,
>> >> +                                               <&pd_cores 2>,
>> >> +                                               <&pd_cores 3>,
>> >> +                                               <&pd_cores 4>,
>> >> +                                               <&pd_cores 5>,
>> >> +                                               <&pd_cores 6>,
>> >> +                                               <&pd_cores 7>;
>> >> +                       };
>> >> +               };
>> >
>> > I noticed while developing the CPUidle generic driver, that by using this
>> > representation I might end up requiring duplicated states.
>> >
>> > For instance, a cluster-retention state and a cluster-sleep state might
>> > want to have cpu-sleep state as substate, and this would require an
>> > idle state node duplication.
>> >
>> > I think it is better to have a single flat (and ordered...that would
>> > kill two birds with one stone) list of nodes in the idle-states node and
>> > every state might have a list of phandles to subnodes (substates), something
>> > like the following example.
>> >
>> > This simplifies parsing  and I think it solves the last issue I
>> > came across (the need for duplicate states - in the bindings below,
>> > CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
>> > CLUSTER_SLEEP_0, through phandles).
>>
>> Hi Lorenzo,
>>
>> You explanation above has triggered a question. You writes:
>> CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
>> that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
>> CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
>> OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
>> can have some in sleep mode and other in retention of course)
>> I'm wondering how this OR  will be described.
>
> We need another state (because that's what happens in HW right ?), so we
> describe it (obviously having different latencies):
>
>
>         CLUSTER_RETENTION_1: cluster-retention-1 {
>                 compatible = "arm,idle-state";
>                 logic-state-retained;
>                 cache-state-retained;
>                 entry-method-param = <0x1010000>;
>                 entry-latency-us = <50>;
>                 exit-latency-us = <700>;
>                 min-residency-us = <2000>;
>                 power-domains = <&pd_clusters 0>;
>                 substates = <&CPU_RETENTION_0>;
>          };
>
> Using phandles all state combinations are now possible, with no state
> duplication.
>
> State above is entered when all CPUs are in retention mode and thanks
> to the phandle the kernel knows what has to be done as far as each
> CPU is concerned. The beauty of this approach is that for every state,
> it is well defined what has to be done for the respective power domain
> (eg state above, cache is retained. All caches in <&pd_clusters 0> are
> retained. Then we follow the substates, and take action according to
> the substate propertes and respective power domain).
>
> Does this make sense ? I can't find fault with this semantics, but
> please let me know if you do.


So we will have some cpus of the cluster in CLUSTER_RETENTION_1 state
and other cpus of the same cluster in CLUSTER_RETENTION_0 depending of
the power state of the cpu part but for the same power state of common
part of the cluster.
How does the driver know that both power states are compatible ? I
mean how the last cpu will know that it can put the cluster in
retention state because all the other cpus of the cluster are in a
compatible state ?

Regards,
Vincent

>
> Thank you !!
> Lorenzo
>
>> Then, IMHO, the flat description below is clearer and remove the
>> duplicated description that you mention previously
>>
>> Regards,
>> Vincent
>>
>> >
>> > Thoughts very appreciated, thanks.
>> >
>> > Lorenzo
>> >
>> > idle-states {
>> >        entry-method = "arm,psci-cpu-suspend";
>> >
>> >         CPU_RETENTION_0: cpu-retention-0 {
>> >                        compatible = "arm,idle-state";
>> >                        cache-state-retained;
>> >                        entry-method-param = <0x0010000>;
>> >                        entry-latency-us = <20>;
>> >                        exit-latency-us = <40>;
>> >                        min-residency-us = <30>;
>> >                        power-domains = <&pd_cores 0>,
>> >                                        <&pd_cores 1>,
>> >                                        <&pd_cores 2>,
>> >                                        <&pd_cores 3>,
>> >         };
>> >
>> >         CPU_SLEEP_0: cpu-sleep-0 {
>> >                        /* cpu sleep */
>> >                        compatible = "arm,idle-state";
>> >                        entry-method-param = <0x0010000>;
>> >                        entry-latency-us = <250>;
>> >                        exit-latency-us = <500>;
>> >                        min-residency-us = <350>;
>> >                        power-domains = <&pd_cores 0>,
>> >                                        <&pd_cores 1>,
>> >                                        <&pd_cores 2>,
>> >                                        <&pd_cores 3>,
>> >         };
>> >
>> >         CPU_SLEEP_1: cpu-sleep-1 {
>> >                        /* cpu sleep */
>> >                        compatible = "arm,idle-state";
>> >                        entry-method-param = <0x0010000>;
>> >                        entry-latency-us = <250>;
>> >                        exit-latency-us = <500>;
>> >                        min-residency-us = <350>;
>> >                                        <&pd_cores 4>,
>> >                                        <&pd_cores 5>,
>> >                                        <&pd_cores 6>,
>> >                                        <&pd_cores 7>;
>> >         };
>> >
>> >         CLUSTER_RETENTION_0: cluster-retention-0 {
>> >                compatible = "arm,idle-state";
>> >                logic-state-retained;
>> >                cache-state-retained;
>> >                entry-method-param = <0x1010000>;
>> >                entry-latency-us = <50>;
>> >                exit-latency-us = <800>;
>> >                min-residency-us = <2400>;
>> >                power-domains = <&pd_clusters 0>;
>> >                substates = <&CPU_SLEEP_0>;
>> >         };
>> >
>> >         CLUSTER_SLEEP_0: cluster-sleep-0 {
>> >                compatible = "arm,idle-state";
>> >                entry-method-param = <0x1010000>;
>> >                entry-latency-us = <600>;
>> >                exit-latency-us = <1100>;
>> >                min-residency-us = <2700>;
>> >                power-domains = <&pd_clusters 0>;
>> >                substates = <&CPU_SLEEP_0>;
>> >         };
>> >
>> >         CLUSTER_SLEEP_1: cluster-sleep-1 {
>> >                compatible = "arm,idle-state";
>> >                entry-method-param = <0x1010000>;
>> >                entry-latency-us = <600>;
>> >                exit-latency-us = <1100>;
>> >                min-residency-us = <2700>;
>> >                power-domains = <&pd_clusters 1>;
>> >                substates = <&CPU_SLEEP_1>;
>> >         };
>> >
>> >         SYSTEM_SLEEP_0: system-sleep-0 {
>> >                compatible = "arm,idle-state";
>> >                entry-method-param = <0x2010000>;
>> >                entry-latency-us = <6000>;
>> >                exit-latency-us = <10000>;
>> >                min-residency-us = <30000>;
>> >                power-domains = <&pd_system 0>;
>> >                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
>> >         };
>> > };
>> >
>>
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-07 15:34           ` Vincent Guittot
  0 siblings, 0 replies; 26+ messages in thread
From: Vincent Guittot @ 2014-04-07 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 7 April 2014 16:36, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Mon, Apr 07, 2014 at 01:25:17PM +0100, Vincent Guittot wrote:
>> On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> > [replying to self, since I have a query]
>> >
>> > [...]
>> >
>> >> +===========================================
>> >> +4 - Examples
>> >> +===========================================
>> >> +
>> >> +Example 1 (ARM 64-bit, 16-cpu system):
>> >> +
>> >> +pd_clusters: power-domain-clusters at 80002000 {
>> >> +       compatible = "arm,power-controller";
>> >> +       reg = <0x0 0x80002000 0x0 0x1000>;
>> >> +       #power-domain-cells = <1>;
>> >> +       #address-cells = <2>;
>> >> +       #size-cells = <2>;
>> >> +
>> >> +       pd_cores: power-domain-cores at 80000000 {
>> >> +               compatible = "arm,power-controller";
>> >> +               reg = <0x0 0x80000000 0x0 0x1000>;
>> >> +               #power-domain-cells = <1>;
>> >> +       };
>> >> +};
>> >> +
>> >> +cpus {
>> >> +       #size-cells = <0>;
>> >> +       #address-cells = <2>;
>> >> +
>> >> +       idle-states {
>> >> +               entry-method = "arm,psci-cpu-suspend";
>> >> +
>> >> +               CLUSTER_RETENTION_0: cluster-retention-0 {
>> >> +                       compatible = "arm,idle-state";
>> >> +                       index = <2>;
>> >> +                       logic-state-retained;
>> >> +                       cache-state-retained;
>> >> +                       entry-method-param = <0x1010000>;
>> >> +                       entry-latency-us = <50>;
>> >> +                       exit-latency-us = <100>;
>> >> +                       min-residency-us = <250>;
>> >> +                       power-domains = <&pd_clusters 0>;
>> >> +                       CPU_RETENTION_0_0: cpu-retention-0 {
>> >> +                               compatible = "arm,idle-state";
>> >> +                               index = <0>;
>> >> +                               cache-state-retained;
>> >> +                               entry-method-param = <0x0010000>;
>> >> +                               entry-latency-us = <20>;
>> >> +                               exit-latency-us = <40>;
>> >> +                               min-residency-us = <30>;
>> >> +                               power-domains = <&pd_cores 0>,
>> >> +                                               <&pd_cores 1>,
>> >> +                                               <&pd_cores 2>,
>> >> +                                               <&pd_cores 3>,
>> >> +                                               <&pd_cores 4>,
>> >> +                                               <&pd_cores 5>,
>> >> +                                               <&pd_cores 6>,
>> >> +                                               <&pd_cores 7>;
>> >> +                       };
>> >> +               };
>> >> +
>> >> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
>> >> +                       compatible = "arm,idle-state";
>> >> +                       index = <3>;
>> >> +                       entry-method-param = <0x1010000>;
>> >> +                       entry-latency-us = <600>;
>> >> +                       exit-latency-us = <1100>;
>> >> +                       min-residency-us = <2700>;
>> >> +                       power-domains = <&pd_clusters 0>;
>> >> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
>> >> +                               /* cpu sleep */
>> >> +                               compatible = "arm,idle-state";
>> >> +                               index = <1>;
>> >> +                               entry-method-param = <0x0010000>;
>> >> +                               entry-latency-us = <250>;
>> >> +                               exit-latency-us = <500>;
>> >> +                               min-residency-us = <350>;
>> >> +                               power-domains = <&pd_cores 0>,
>> >> +                                               <&pd_cores 1>,
>> >> +                                               <&pd_cores 2>,
>> >> +                                               <&pd_cores 3>,
>> >> +                                               <&pd_cores 4>,
>> >> +                                               <&pd_cores 5>,
>> >> +                                               <&pd_cores 6>,
>> >> +                                               <&pd_cores 7>;
>> >> +                       };
>> >> +               };
>> >
>> > I noticed while developing the CPUidle generic driver, that by using this
>> > representation I might end up requiring duplicated states.
>> >
>> > For instance, a cluster-retention state and a cluster-sleep state might
>> > want to have cpu-sleep state as substate, and this would require an
>> > idle state node duplication.
>> >
>> > I think it is better to have a single flat (and ordered...that would
>> > kill two birds with one stone) list of nodes in the idle-states node and
>> > every state might have a list of phandles to subnodes (substates), something
>> > like the following example.
>> >
>> > This simplifies parsing  and I think it solves the last issue I
>> > came across (the need for duplicate states - in the bindings below,
>> > CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
>> > CLUSTER_SLEEP_0, through phandles).
>>
>> Hi Lorenzo,
>>
>> You explanation above has triggered a question. You writes:
>> CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
>> that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
>> CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
>> OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
>> can have some in sleep mode and other in retention of course)
>> I'm wondering how this OR  will be described.
>
> We need another state (because that's what happens in HW right ?), so we
> describe it (obviously having different latencies):
>
>
>         CLUSTER_RETENTION_1: cluster-retention-1 {
>                 compatible = "arm,idle-state";
>                 logic-state-retained;
>                 cache-state-retained;
>                 entry-method-param = <0x1010000>;
>                 entry-latency-us = <50>;
>                 exit-latency-us = <700>;
>                 min-residency-us = <2000>;
>                 power-domains = <&pd_clusters 0>;
>                 substates = <&CPU_RETENTION_0>;
>          };
>
> Using phandles all state combinations are now possible, with no state
> duplication.
>
> State above is entered when all CPUs are in retention mode and thanks
> to the phandle the kernel knows what has to be done as far as each
> CPU is concerned. The beauty of this approach is that for every state,
> it is well defined what has to be done for the respective power domain
> (eg state above, cache is retained. All caches in <&pd_clusters 0> are
> retained. Then we follow the substates, and take action according to
> the substate propertes and respective power domain).
>
> Does this make sense ? I can't find fault with this semantics, but
> please let me know if you do.


So we will have some cpus of the cluster in CLUSTER_RETENTION_1 state
and other cpus of the same cluster in CLUSTER_RETENTION_0 depending of
the power state of the cpu part but for the same power state of common
part of the cluster.
How does the driver know that both power states are compatible ? I
mean how the last cpu will know that it can put the cluster in
retention state because all the other cpus of the cluster are in a
compatible state ?

Regards,
Vincent

>
> Thank you !!
> Lorenzo
>
>> Then, IMHO, the flat description below is clearer and remove the
>> duplicated description that you mention previously
>>
>> Regards,
>> Vincent
>>
>> >
>> > Thoughts very appreciated, thanks.
>> >
>> > Lorenzo
>> >
>> > idle-states {
>> >        entry-method = "arm,psci-cpu-suspend";
>> >
>> >         CPU_RETENTION_0: cpu-retention-0 {
>> >                        compatible = "arm,idle-state";
>> >                        cache-state-retained;
>> >                        entry-method-param = <0x0010000>;
>> >                        entry-latency-us = <20>;
>> >                        exit-latency-us = <40>;
>> >                        min-residency-us = <30>;
>> >                        power-domains = <&pd_cores 0>,
>> >                                        <&pd_cores 1>,
>> >                                        <&pd_cores 2>,
>> >                                        <&pd_cores 3>,
>> >         };
>> >
>> >         CPU_SLEEP_0: cpu-sleep-0 {
>> >                        /* cpu sleep */
>> >                        compatible = "arm,idle-state";
>> >                        entry-method-param = <0x0010000>;
>> >                        entry-latency-us = <250>;
>> >                        exit-latency-us = <500>;
>> >                        min-residency-us = <350>;
>> >                        power-domains = <&pd_cores 0>,
>> >                                        <&pd_cores 1>,
>> >                                        <&pd_cores 2>,
>> >                                        <&pd_cores 3>,
>> >         };
>> >
>> >         CPU_SLEEP_1: cpu-sleep-1 {
>> >                        /* cpu sleep */
>> >                        compatible = "arm,idle-state";
>> >                        entry-method-param = <0x0010000>;
>> >                        entry-latency-us = <250>;
>> >                        exit-latency-us = <500>;
>> >                        min-residency-us = <350>;
>> >                                        <&pd_cores 4>,
>> >                                        <&pd_cores 5>,
>> >                                        <&pd_cores 6>,
>> >                                        <&pd_cores 7>;
>> >         };
>> >
>> >         CLUSTER_RETENTION_0: cluster-retention-0 {
>> >                compatible = "arm,idle-state";
>> >                logic-state-retained;
>> >                cache-state-retained;
>> >                entry-method-param = <0x1010000>;
>> >                entry-latency-us = <50>;
>> >                exit-latency-us = <800>;
>> >                min-residency-us = <2400>;
>> >                power-domains = <&pd_clusters 0>;
>> >                substates = <&CPU_SLEEP_0>;
>> >         };
>> >
>> >         CLUSTER_SLEEP_0: cluster-sleep-0 {
>> >                compatible = "arm,idle-state";
>> >                entry-method-param = <0x1010000>;
>> >                entry-latency-us = <600>;
>> >                exit-latency-us = <1100>;
>> >                min-residency-us = <2700>;
>> >                power-domains = <&pd_clusters 0>;
>> >                substates = <&CPU_SLEEP_0>;
>> >         };
>> >
>> >         CLUSTER_SLEEP_1: cluster-sleep-1 {
>> >                compatible = "arm,idle-state";
>> >                entry-method-param = <0x1010000>;
>> >                entry-latency-us = <600>;
>> >                exit-latency-us = <1100>;
>> >                min-residency-us = <2700>;
>> >                power-domains = <&pd_clusters 1>;
>> >                substates = <&CPU_SLEEP_1>;
>> >         };
>> >
>> >         SYSTEM_SLEEP_0: system-sleep-0 {
>> >                compatible = "arm,idle-state";
>> >                entry-method-param = <0x2010000>;
>> >                entry-latency-us = <6000>;
>> >                exit-latency-us = <10000>;
>> >                min-residency-us = <30000>;
>> >                power-domains = <&pd_system 0>;
>> >                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
>> >         };
>> > };
>> >
>>
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-04-07 15:34           ` Vincent Guittot
@ 2014-04-07 18:03             ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-07 18:03 UTC (permalink / raw)
  To: Vincent Guittot
  Cc: Mark Rutland, Tomasz Figa, Mark Hambleton, Russell King,
	Sebastian Capella, Nicolas Pitre, Daniel Lezcano,
	linux-arm-kernel, grant.likely, Dave P Martin,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Mike Turquette, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd

On Mon, Apr 07, 2014 at 04:34:49PM +0100, Vincent Guittot wrote:
> On 7 April 2014 16:36, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> > On Mon, Apr 07, 2014 at 01:25:17PM +0100, Vincent Guittot wrote:
> >> On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> >> > [replying to self, since I have a query]
> >> >
> >> > [...]
> >> >
> >> >> +===========================================
> >> >> +4 - Examples
> >> >> +===========================================
> >> >> +
> >> >> +Example 1 (ARM 64-bit, 16-cpu system):
> >> >> +
> >> >> +pd_clusters: power-domain-clusters@80002000 {
> >> >> +       compatible = "arm,power-controller";
> >> >> +       reg = <0x0 0x80002000 0x0 0x1000>;
> >> >> +       #power-domain-cells = <1>;
> >> >> +       #address-cells = <2>;
> >> >> +       #size-cells = <2>;
> >> >> +
> >> >> +       pd_cores: power-domain-cores@80000000 {
> >> >> +               compatible = "arm,power-controller";
> >> >> +               reg = <0x0 0x80000000 0x0 0x1000>;
> >> >> +               #power-domain-cells = <1>;
> >> >> +       };
> >> >> +};
> >> >> +
> >> >> +cpus {
> >> >> +       #size-cells = <0>;
> >> >> +       #address-cells = <2>;
> >> >> +
> >> >> +       idle-states {
> >> >> +               entry-method = "arm,psci-cpu-suspend";
> >> >> +
> >> >> +               CLUSTER_RETENTION_0: cluster-retention-0 {
> >> >> +                       compatible = "arm,idle-state";
> >> >> +                       index = <2>;
> >> >> +                       logic-state-retained;
> >> >> +                       cache-state-retained;
> >> >> +                       entry-method-param = <0x1010000>;
> >> >> +                       entry-latency-us = <50>;
> >> >> +                       exit-latency-us = <100>;
> >> >> +                       min-residency-us = <250>;
> >> >> +                       power-domains = <&pd_clusters 0>;
> >> >> +                       CPU_RETENTION_0_0: cpu-retention-0 {
> >> >> +                               compatible = "arm,idle-state";
> >> >> +                               index = <0>;
> >> >> +                               cache-state-retained;
> >> >> +                               entry-method-param = <0x0010000>;
> >> >> +                               entry-latency-us = <20>;
> >> >> +                               exit-latency-us = <40>;
> >> >> +                               min-residency-us = <30>;
> >> >> +                               power-domains = <&pd_cores 0>,
> >> >> +                                               <&pd_cores 1>,
> >> >> +                                               <&pd_cores 2>,
> >> >> +                                               <&pd_cores 3>,
> >> >> +                                               <&pd_cores 4>,
> >> >> +                                               <&pd_cores 5>,
> >> >> +                                               <&pd_cores 6>,
> >> >> +                                               <&pd_cores 7>;
> >> >> +                       };
> >> >> +               };
> >> >> +
> >> >> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> >> >> +                       compatible = "arm,idle-state";
> >> >> +                       index = <3>;
> >> >> +                       entry-method-param = <0x1010000>;
> >> >> +                       entry-latency-us = <600>;
> >> >> +                       exit-latency-us = <1100>;
> >> >> +                       min-residency-us = <2700>;
> >> >> +                       power-domains = <&pd_clusters 0>;
> >> >> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> >> >> +                               /* cpu sleep */
> >> >> +                               compatible = "arm,idle-state";
> >> >> +                               index = <1>;
> >> >> +                               entry-method-param = <0x0010000>;
> >> >> +                               entry-latency-us = <250>;
> >> >> +                               exit-latency-us = <500>;
> >> >> +                               min-residency-us = <350>;
> >> >> +                               power-domains = <&pd_cores 0>,
> >> >> +                                               <&pd_cores 1>,
> >> >> +                                               <&pd_cores 2>,
> >> >> +                                               <&pd_cores 3>,
> >> >> +                                               <&pd_cores 4>,
> >> >> +                                               <&pd_cores 5>,
> >> >> +                                               <&pd_cores 6>,
> >> >> +                                               <&pd_cores 7>;
> >> >> +                       };
> >> >> +               };
> >> >
> >> > I noticed while developing the CPUidle generic driver, that by using this
> >> > representation I might end up requiring duplicated states.
> >> >
> >> > For instance, a cluster-retention state and a cluster-sleep state might
> >> > want to have cpu-sleep state as substate, and this would require an
> >> > idle state node duplication.
> >> >
> >> > I think it is better to have a single flat (and ordered...that would
> >> > kill two birds with one stone) list of nodes in the idle-states node and
> >> > every state might have a list of phandles to subnodes (substates), something
> >> > like the following example.
> >> >
> >> > This simplifies parsing  and I think it solves the last issue I
> >> > came across (the need for duplicate states - in the bindings below,
> >> > CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
> >> > CLUSTER_SLEEP_0, through phandles).
> >>
> >> Hi Lorenzo,
> >>
> >> You explanation above has triggered a question. You writes:
> >> CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
> >> that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
> >> CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
> >> OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
> >> can have some in sleep mode and other in retention of course)
> >> I'm wondering how this OR  will be described.
> >
> > We need another state (because that's what happens in HW right ?), so we
> > describe it (obviously having different latencies):
> >
> >
> >         CLUSTER_RETENTION_1: cluster-retention-1 {
> >                 compatible = "arm,idle-state";
> >                 logic-state-retained;
> >                 cache-state-retained;
> >                 entry-method-param = <0x1010000>;
> >                 entry-latency-us = <50>;
> >                 exit-latency-us = <700>;
> >                 min-residency-us = <2000>;
> >                 power-domains = <&pd_clusters 0>;
> >                 substates = <&CPU_RETENTION_0>;
> >          };
> >
> > Using phandles all state combinations are now possible, with no state
> > duplication.
> >
> > State above is entered when all CPUs are in retention mode and thanks
> > to the phandle the kernel knows what has to be done as far as each
> > CPU is concerned. The beauty of this approach is that for every state,
> > it is well defined what has to be done for the respective power domain
> > (eg state above, cache is retained. All caches in <&pd_clusters 0> are
> > retained. Then we follow the substates, and take action according to
> > the substate propertes and respective power domain).
> >
> > Does this make sense ? I can't find fault with this semantics, but
> > please let me know if you do.
> 
> 
> So we will have some cpus of the cluster in CLUSTER_RETENTION_1 state
> and other cpus of the same cluster in CLUSTER_RETENTION_0 depending of
> the power state of the cpu part but for the same power state of common
> part of the cluster.
> How does the driver know that both power states are compatible ? I
> mean how the last cpu will know that it can put the cluster in
> retention state because all the other cpus of the cluster are in a
> compatible state ?

Short answer: the power domain hierarchy will define what CPUs are in what
power domain. For states that encompass multiple cpus for them to be valid,
we just use the lowest common index approach (I am talking about index in the
idle state order - which, if the list is flat and ordered in terms of power
savings is easy to define).

That's how idle works today, I am not adding anything new.

If:

CLUSTER_RETENTION_0  - index 2
CLUSTER_RETENTION_1  - index 3

Cleraly if some CPUs are in index 3 and some in 2, 2 must be chosen.

This demotion is easy to carry out with the information in the bindings.
If a state affect power domains that span multiples CPUs (and not only
CPUs....), all CPUs (+ devices) must be in that state (or "higher") for it
to be valid.

If not, demotion should take place (or put it differently that state
becomes invalid).

A LUT should be sufficient for a CPU to detect what it has to do upon
state entry.

I will give it more thought but I think the information in the bindings
is still sufficient to pull this off.

I am a bit concerned about the power domains representation in the DT, I
will think more about this too and keep you posted.

Thanks,
Lorenzo

> 
> Regards,
> Vincent
> 
> >
> > Thank you !!
> > Lorenzo
> >
> >> Then, IMHO, the flat description below is clearer and remove the
> >> duplicated description that you mention previously
> >>
> >> Regards,
> >> Vincent
> >>
> >> >
> >> > Thoughts very appreciated, thanks.
> >> >
> >> > Lorenzo
> >> >
> >> > idle-states {
> >> >        entry-method = "arm,psci-cpu-suspend";
> >> >
> >> >         CPU_RETENTION_0: cpu-retention-0 {
> >> >                        compatible = "arm,idle-state";
> >> >                        cache-state-retained;
> >> >                        entry-method-param = <0x0010000>;
> >> >                        entry-latency-us = <20>;
> >> >                        exit-latency-us = <40>;
> >> >                        min-residency-us = <30>;
> >> >                        power-domains = <&pd_cores 0>,
> >> >                                        <&pd_cores 1>,
> >> >                                        <&pd_cores 2>,
> >> >                                        <&pd_cores 3>,
> >> >         };
> >> >
> >> >         CPU_SLEEP_0: cpu-sleep-0 {
> >> >                        /* cpu sleep */
> >> >                        compatible = "arm,idle-state";
> >> >                        entry-method-param = <0x0010000>;
> >> >                        entry-latency-us = <250>;
> >> >                        exit-latency-us = <500>;
> >> >                        min-residency-us = <350>;
> >> >                        power-domains = <&pd_cores 0>,
> >> >                                        <&pd_cores 1>,
> >> >                                        <&pd_cores 2>,
> >> >                                        <&pd_cores 3>,
> >> >         };
> >> >
> >> >         CPU_SLEEP_1: cpu-sleep-1 {
> >> >                        /* cpu sleep */
> >> >                        compatible = "arm,idle-state";
> >> >                        entry-method-param = <0x0010000>;
> >> >                        entry-latency-us = <250>;
> >> >                        exit-latency-us = <500>;
> >> >                        min-residency-us = <350>;
> >> >                                        <&pd_cores 4>,
> >> >                                        <&pd_cores 5>,
> >> >                                        <&pd_cores 6>,
> >> >                                        <&pd_cores 7>;
> >> >         };
> >> >
> >> >         CLUSTER_RETENTION_0: cluster-retention-0 {
> >> >                compatible = "arm,idle-state";
> >> >                logic-state-retained;
> >> >                cache-state-retained;
> >> >                entry-method-param = <0x1010000>;
> >> >                entry-latency-us = <50>;
> >> >                exit-latency-us = <800>;
> >> >                min-residency-us = <2400>;
> >> >                power-domains = <&pd_clusters 0>;
> >> >                substates = <&CPU_SLEEP_0>;
> >> >         };
> >> >
> >> >         CLUSTER_SLEEP_0: cluster-sleep-0 {
> >> >                compatible = "arm,idle-state";
> >> >                entry-method-param = <0x1010000>;
> >> >                entry-latency-us = <600>;
> >> >                exit-latency-us = <1100>;
> >> >                min-residency-us = <2700>;
> >> >                power-domains = <&pd_clusters 0>;
> >> >                substates = <&CPU_SLEEP_0>;
> >> >         };
> >> >
> >> >         CLUSTER_SLEEP_1: cluster-sleep-1 {
> >> >                compatible = "arm,idle-state";
> >> >                entry-method-param = <0x1010000>;
> >> >                entry-latency-us = <600>;
> >> >                exit-latency-us = <1100>;
> >> >                min-residency-us = <2700>;
> >> >                power-domains = <&pd_clusters 1>;
> >> >                substates = <&CPU_SLEEP_1>;
> >> >         };
> >> >
> >> >         SYSTEM_SLEEP_0: system-sleep-0 {
> >> >                compatible = "arm,idle-state";
> >> >                entry-method-param = <0x2010000>;
> >> >                entry-latency-us = <6000>;
> >> >                exit-latency-us = <10000>;
> >> >                min-residency-us = <30000>;
> >> >                power-domains = <&pd_system 0>;
> >> >                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
> >> >         };
> >> > };
> >> >
> >>
> >
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-07 18:03             ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-07 18:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 07, 2014 at 04:34:49PM +0100, Vincent Guittot wrote:
> On 7 April 2014 16:36, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> > On Mon, Apr 07, 2014 at 01:25:17PM +0100, Vincent Guittot wrote:
> >> On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> >> > [replying to self, since I have a query]
> >> >
> >> > [...]
> >> >
> >> >> +===========================================
> >> >> +4 - Examples
> >> >> +===========================================
> >> >> +
> >> >> +Example 1 (ARM 64-bit, 16-cpu system):
> >> >> +
> >> >> +pd_clusters: power-domain-clusters at 80002000 {
> >> >> +       compatible = "arm,power-controller";
> >> >> +       reg = <0x0 0x80002000 0x0 0x1000>;
> >> >> +       #power-domain-cells = <1>;
> >> >> +       #address-cells = <2>;
> >> >> +       #size-cells = <2>;
> >> >> +
> >> >> +       pd_cores: power-domain-cores at 80000000 {
> >> >> +               compatible = "arm,power-controller";
> >> >> +               reg = <0x0 0x80000000 0x0 0x1000>;
> >> >> +               #power-domain-cells = <1>;
> >> >> +       };
> >> >> +};
> >> >> +
> >> >> +cpus {
> >> >> +       #size-cells = <0>;
> >> >> +       #address-cells = <2>;
> >> >> +
> >> >> +       idle-states {
> >> >> +               entry-method = "arm,psci-cpu-suspend";
> >> >> +
> >> >> +               CLUSTER_RETENTION_0: cluster-retention-0 {
> >> >> +                       compatible = "arm,idle-state";
> >> >> +                       index = <2>;
> >> >> +                       logic-state-retained;
> >> >> +                       cache-state-retained;
> >> >> +                       entry-method-param = <0x1010000>;
> >> >> +                       entry-latency-us = <50>;
> >> >> +                       exit-latency-us = <100>;
> >> >> +                       min-residency-us = <250>;
> >> >> +                       power-domains = <&pd_clusters 0>;
> >> >> +                       CPU_RETENTION_0_0: cpu-retention-0 {
> >> >> +                               compatible = "arm,idle-state";
> >> >> +                               index = <0>;
> >> >> +                               cache-state-retained;
> >> >> +                               entry-method-param = <0x0010000>;
> >> >> +                               entry-latency-us = <20>;
> >> >> +                               exit-latency-us = <40>;
> >> >> +                               min-residency-us = <30>;
> >> >> +                               power-domains = <&pd_cores 0>,
> >> >> +                                               <&pd_cores 1>,
> >> >> +                                               <&pd_cores 2>,
> >> >> +                                               <&pd_cores 3>,
> >> >> +                                               <&pd_cores 4>,
> >> >> +                                               <&pd_cores 5>,
> >> >> +                                               <&pd_cores 6>,
> >> >> +                                               <&pd_cores 7>;
> >> >> +                       };
> >> >> +               };
> >> >> +
> >> >> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> >> >> +                       compatible = "arm,idle-state";
> >> >> +                       index = <3>;
> >> >> +                       entry-method-param = <0x1010000>;
> >> >> +                       entry-latency-us = <600>;
> >> >> +                       exit-latency-us = <1100>;
> >> >> +                       min-residency-us = <2700>;
> >> >> +                       power-domains = <&pd_clusters 0>;
> >> >> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> >> >> +                               /* cpu sleep */
> >> >> +                               compatible = "arm,idle-state";
> >> >> +                               index = <1>;
> >> >> +                               entry-method-param = <0x0010000>;
> >> >> +                               entry-latency-us = <250>;
> >> >> +                               exit-latency-us = <500>;
> >> >> +                               min-residency-us = <350>;
> >> >> +                               power-domains = <&pd_cores 0>,
> >> >> +                                               <&pd_cores 1>,
> >> >> +                                               <&pd_cores 2>,
> >> >> +                                               <&pd_cores 3>,
> >> >> +                                               <&pd_cores 4>,
> >> >> +                                               <&pd_cores 5>,
> >> >> +                                               <&pd_cores 6>,
> >> >> +                                               <&pd_cores 7>;
> >> >> +                       };
> >> >> +               };
> >> >
> >> > I noticed while developing the CPUidle generic driver, that by using this
> >> > representation I might end up requiring duplicated states.
> >> >
> >> > For instance, a cluster-retention state and a cluster-sleep state might
> >> > want to have cpu-sleep state as substate, and this would require an
> >> > idle state node duplication.
> >> >
> >> > I think it is better to have a single flat (and ordered...that would
> >> > kill two birds with one stone) list of nodes in the idle-states node and
> >> > every state might have a list of phandles to subnodes (substates), something
> >> > like the following example.
> >> >
> >> > This simplifies parsing  and I think it solves the last issue I
> >> > came across (the need for duplicate states - in the bindings below,
> >> > CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
> >> > CLUSTER_SLEEP_0, through phandles).
> >>
> >> Hi Lorenzo,
> >>
> >> You explanation above has triggered a question. You writes:
> >> CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
> >> that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
> >> CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
> >> OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
> >> can have some in sleep mode and other in retention of course)
> >> I'm wondering how this OR  will be described.
> >
> > We need another state (because that's what happens in HW right ?), so we
> > describe it (obviously having different latencies):
> >
> >
> >         CLUSTER_RETENTION_1: cluster-retention-1 {
> >                 compatible = "arm,idle-state";
> >                 logic-state-retained;
> >                 cache-state-retained;
> >                 entry-method-param = <0x1010000>;
> >                 entry-latency-us = <50>;
> >                 exit-latency-us = <700>;
> >                 min-residency-us = <2000>;
> >                 power-domains = <&pd_clusters 0>;
> >                 substates = <&CPU_RETENTION_0>;
> >          };
> >
> > Using phandles all state combinations are now possible, with no state
> > duplication.
> >
> > State above is entered when all CPUs are in retention mode and thanks
> > to the phandle the kernel knows what has to be done as far as each
> > CPU is concerned. The beauty of this approach is that for every state,
> > it is well defined what has to be done for the respective power domain
> > (eg state above, cache is retained. All caches in <&pd_clusters 0> are
> > retained. Then we follow the substates, and take action according to
> > the substate propertes and respective power domain).
> >
> > Does this make sense ? I can't find fault with this semantics, but
> > please let me know if you do.
> 
> 
> So we will have some cpus of the cluster in CLUSTER_RETENTION_1 state
> and other cpus of the same cluster in CLUSTER_RETENTION_0 depending of
> the power state of the cpu part but for the same power state of common
> part of the cluster.
> How does the driver know that both power states are compatible ? I
> mean how the last cpu will know that it can put the cluster in
> retention state because all the other cpus of the cluster are in a
> compatible state ?

Short answer: the power domain hierarchy will define what CPUs are in what
power domain. For states that encompass multiple cpus for them to be valid,
we just use the lowest common index approach (I am talking about index in the
idle state order - which, if the list is flat and ordered in terms of power
savings is easy to define).

That's how idle works today, I am not adding anything new.

If:

CLUSTER_RETENTION_0  - index 2
CLUSTER_RETENTION_1  - index 3

Cleraly if some CPUs are in index 3 and some in 2, 2 must be chosen.

This demotion is easy to carry out with the information in the bindings.
If a state affect power domains that span multiples CPUs (and not only
CPUs....), all CPUs (+ devices) must be in that state (or "higher") for it
to be valid.

If not, demotion should take place (or put it differently that state
becomes invalid).

A LUT should be sufficient for a CPU to detect what it has to do upon
state entry.

I will give it more thought but I think the information in the bindings
is still sufficient to pull this off.

I am a bit concerned about the power domains representation in the DT, I
will think more about this too and keep you posted.

Thanks,
Lorenzo

> 
> Regards,
> Vincent
> 
> >
> > Thank you !!
> > Lorenzo
> >
> >> Then, IMHO, the flat description below is clearer and remove the
> >> duplicated description that you mention previously
> >>
> >> Regards,
> >> Vincent
> >>
> >> >
> >> > Thoughts very appreciated, thanks.
> >> >
> >> > Lorenzo
> >> >
> >> > idle-states {
> >> >        entry-method = "arm,psci-cpu-suspend";
> >> >
> >> >         CPU_RETENTION_0: cpu-retention-0 {
> >> >                        compatible = "arm,idle-state";
> >> >                        cache-state-retained;
> >> >                        entry-method-param = <0x0010000>;
> >> >                        entry-latency-us = <20>;
> >> >                        exit-latency-us = <40>;
> >> >                        min-residency-us = <30>;
> >> >                        power-domains = <&pd_cores 0>,
> >> >                                        <&pd_cores 1>,
> >> >                                        <&pd_cores 2>,
> >> >                                        <&pd_cores 3>,
> >> >         };
> >> >
> >> >         CPU_SLEEP_0: cpu-sleep-0 {
> >> >                        /* cpu sleep */
> >> >                        compatible = "arm,idle-state";
> >> >                        entry-method-param = <0x0010000>;
> >> >                        entry-latency-us = <250>;
> >> >                        exit-latency-us = <500>;
> >> >                        min-residency-us = <350>;
> >> >                        power-domains = <&pd_cores 0>,
> >> >                                        <&pd_cores 1>,
> >> >                                        <&pd_cores 2>,
> >> >                                        <&pd_cores 3>,
> >> >         };
> >> >
> >> >         CPU_SLEEP_1: cpu-sleep-1 {
> >> >                        /* cpu sleep */
> >> >                        compatible = "arm,idle-state";
> >> >                        entry-method-param = <0x0010000>;
> >> >                        entry-latency-us = <250>;
> >> >                        exit-latency-us = <500>;
> >> >                        min-residency-us = <350>;
> >> >                                        <&pd_cores 4>,
> >> >                                        <&pd_cores 5>,
> >> >                                        <&pd_cores 6>,
> >> >                                        <&pd_cores 7>;
> >> >         };
> >> >
> >> >         CLUSTER_RETENTION_0: cluster-retention-0 {
> >> >                compatible = "arm,idle-state";
> >> >                logic-state-retained;
> >> >                cache-state-retained;
> >> >                entry-method-param = <0x1010000>;
> >> >                entry-latency-us = <50>;
> >> >                exit-latency-us = <800>;
> >> >                min-residency-us = <2400>;
> >> >                power-domains = <&pd_clusters 0>;
> >> >                substates = <&CPU_SLEEP_0>;
> >> >         };
> >> >
> >> >         CLUSTER_SLEEP_0: cluster-sleep-0 {
> >> >                compatible = "arm,idle-state";
> >> >                entry-method-param = <0x1010000>;
> >> >                entry-latency-us = <600>;
> >> >                exit-latency-us = <1100>;
> >> >                min-residency-us = <2700>;
> >> >                power-domains = <&pd_clusters 0>;
> >> >                substates = <&CPU_SLEEP_0>;
> >> >         };
> >> >
> >> >         CLUSTER_SLEEP_1: cluster-sleep-1 {
> >> >                compatible = "arm,idle-state";
> >> >                entry-method-param = <0x1010000>;
> >> >                entry-latency-us = <600>;
> >> >                exit-latency-us = <1100>;
> >> >                min-residency-us = <2700>;
> >> >                power-domains = <&pd_clusters 1>;
> >> >                substates = <&CPU_SLEEP_1>;
> >> >         };
> >> >
> >> >         SYSTEM_SLEEP_0: system-sleep-0 {
> >> >                compatible = "arm,idle-state";
> >> >                entry-method-param = <0x2010000>;
> >> >                entry-latency-us = <6000>;
> >> >                exit-latency-us = <10000>;
> >> >                min-residency-us = <30000>;
> >> >                power-domains = <&pd_system 0>;
> >> >                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
> >> >         };
> >> > };
> >> >
> >>
> >
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-04-07 18:03             ` Lorenzo Pieralisi
@ 2014-04-08  9:11               ` Vincent Guittot
  -1 siblings, 0 replies; 26+ messages in thread
From: Vincent Guittot @ 2014-04-08  9:11 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Mark Rutland, Tomasz Figa, Mark Hambleton, Russell King,
	Sebastian Capella, Nicolas Pitre, Daniel Lezcano,
	linux-arm-kernel, grant.likely, Dave P Martin,
	Charles Garcia-Tobin, devicetree, Kevin Hilman, linux-pm,
	Kumar Gala, Rob Herring, Mike Turquette, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd

On 7 April 2014 20:03, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Mon, Apr 07, 2014 at 04:34:49PM +0100, Vincent Guittot wrote:
>> On 7 April 2014 16:36, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> > On Mon, Apr 07, 2014 at 01:25:17PM +0100, Vincent Guittot wrote:
>> >> On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> >> > [replying to self, since I have a query]
>> >> >
>> >> > [...]
>> >> >
>> >> >> +===========================================
>> >> >> +4 - Examples
>> >> >> +===========================================
>> >> >> +
>> >> >> +Example 1 (ARM 64-bit, 16-cpu system):
>> >> >> +
>> >> >> +pd_clusters: power-domain-clusters@80002000 {
>> >> >> +       compatible = "arm,power-controller";
>> >> >> +       reg = <0x0 0x80002000 0x0 0x1000>;
>> >> >> +       #power-domain-cells = <1>;
>> >> >> +       #address-cells = <2>;
>> >> >> +       #size-cells = <2>;
>> >> >> +
>> >> >> +       pd_cores: power-domain-cores@80000000 {
>> >> >> +               compatible = "arm,power-controller";
>> >> >> +               reg = <0x0 0x80000000 0x0 0x1000>;
>> >> >> +               #power-domain-cells = <1>;
>> >> >> +       };
>> >> >> +};
>> >> >> +
>> >> >> +cpus {
>> >> >> +       #size-cells = <0>;
>> >> >> +       #address-cells = <2>;
>> >> >> +
>> >> >> +       idle-states {
>> >> >> +               entry-method = "arm,psci-cpu-suspend";
>> >> >> +
>> >> >> +               CLUSTER_RETENTION_0: cluster-retention-0 {
>> >> >> +                       compatible = "arm,idle-state";
>> >> >> +                       index = <2>;
>> >> >> +                       logic-state-retained;
>> >> >> +                       cache-state-retained;
>> >> >> +                       entry-method-param = <0x1010000>;
>> >> >> +                       entry-latency-us = <50>;
>> >> >> +                       exit-latency-us = <100>;
>> >> >> +                       min-residency-us = <250>;
>> >> >> +                       power-domains = <&pd_clusters 0>;
>> >> >> +                       CPU_RETENTION_0_0: cpu-retention-0 {
>> >> >> +                               compatible = "arm,idle-state";
>> >> >> +                               index = <0>;
>> >> >> +                               cache-state-retained;
>> >> >> +                               entry-method-param = <0x0010000>;
>> >> >> +                               entry-latency-us = <20>;
>> >> >> +                               exit-latency-us = <40>;
>> >> >> +                               min-residency-us = <30>;
>> >> >> +                               power-domains = <&pd_cores 0>,
>> >> >> +                                               <&pd_cores 1>,
>> >> >> +                                               <&pd_cores 2>,
>> >> >> +                                               <&pd_cores 3>,
>> >> >> +                                               <&pd_cores 4>,
>> >> >> +                                               <&pd_cores 5>,
>> >> >> +                                               <&pd_cores 6>,
>> >> >> +                                               <&pd_cores 7>;
>> >> >> +                       };
>> >> >> +               };
>> >> >> +
>> >> >> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
>> >> >> +                       compatible = "arm,idle-state";
>> >> >> +                       index = <3>;
>> >> >> +                       entry-method-param = <0x1010000>;
>> >> >> +                       entry-latency-us = <600>;
>> >> >> +                       exit-latency-us = <1100>;
>> >> >> +                       min-residency-us = <2700>;
>> >> >> +                       power-domains = <&pd_clusters 0>;
>> >> >> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
>> >> >> +                               /* cpu sleep */
>> >> >> +                               compatible = "arm,idle-state";
>> >> >> +                               index = <1>;
>> >> >> +                               entry-method-param = <0x0010000>;
>> >> >> +                               entry-latency-us = <250>;
>> >> >> +                               exit-latency-us = <500>;
>> >> >> +                               min-residency-us = <350>;
>> >> >> +                               power-domains = <&pd_cores 0>,
>> >> >> +                                               <&pd_cores 1>,
>> >> >> +                                               <&pd_cores 2>,
>> >> >> +                                               <&pd_cores 3>,
>> >> >> +                                               <&pd_cores 4>,
>> >> >> +                                               <&pd_cores 5>,
>> >> >> +                                               <&pd_cores 6>,
>> >> >> +                                               <&pd_cores 7>;
>> >> >> +                       };
>> >> >> +               };
>> >> >
>> >> > I noticed while developing the CPUidle generic driver, that by using this
>> >> > representation I might end up requiring duplicated states.
>> >> >
>> >> > For instance, a cluster-retention state and a cluster-sleep state might
>> >> > want to have cpu-sleep state as substate, and this would require an
>> >> > idle state node duplication.
>> >> >
>> >> > I think it is better to have a single flat (and ordered...that would
>> >> > kill two birds with one stone) list of nodes in the idle-states node and
>> >> > every state might have a list of phandles to subnodes (substates), something
>> >> > like the following example.
>> >> >
>> >> > This simplifies parsing  and I think it solves the last issue I
>> >> > came across (the need for duplicate states - in the bindings below,
>> >> > CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
>> >> > CLUSTER_SLEEP_0, through phandles).
>> >>
>> >> Hi Lorenzo,
>> >>
>> >> You explanation above has triggered a question. You writes:
>> >> CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
>> >> that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
>> >> CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
>> >> OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
>> >> can have some in sleep mode and other in retention of course)
>> >> I'm wondering how this OR  will be described.
>> >
>> > We need another state (because that's what happens in HW right ?), so we
>> > describe it (obviously having different latencies):
>> >
>> >
>> >         CLUSTER_RETENTION_1: cluster-retention-1 {
>> >                 compatible = "arm,idle-state";
>> >                 logic-state-retained;
>> >                 cache-state-retained;
>> >                 entry-method-param = <0x1010000>;
>> >                 entry-latency-us = <50>;
>> >                 exit-latency-us = <700>;
>> >                 min-residency-us = <2000>;
>> >                 power-domains = <&pd_clusters 0>;
>> >                 substates = <&CPU_RETENTION_0>;
>> >          };
>> >
>> > Using phandles all state combinations are now possible, with no state
>> > duplication.
>> >
>> > State above is entered when all CPUs are in retention mode and thanks
>> > to the phandle the kernel knows what has to be done as far as each
>> > CPU is concerned. The beauty of this approach is that for every state,
>> > it is well defined what has to be done for the respective power domain
>> > (eg state above, cache is retained. All caches in <&pd_clusters 0> are
>> > retained. Then we follow the substates, and take action according to
>> > the substate propertes and respective power domain).
>> >
>> > Does this make sense ? I can't find fault with this semantics, but
>> > please let me know if you do.
>>
>>
>> So we will have some cpus of the cluster in CLUSTER_RETENTION_1 state
>> and other cpus of the same cluster in CLUSTER_RETENTION_0 depending of
>> the power state of the cpu part but for the same power state of common
>> part of the cluster.
>> How does the driver know that both power states are compatible ? I
>> mean how the last cpu will know that it can put the cluster in
>> retention state because all the other cpus of the cluster are in a
>> compatible state ?
>
> Short answer: the power domain hierarchy will define what CPUs are in what
> power domain. For states that encompass multiple cpus for them to be valid,
> we just use the lowest common index approach (I am talking about index in the
> idle state order - which, if the list is flat and ordered in terms of power
> savings is easy to define).
>
> That's how idle works today, I am not adding anything new.

I agree but today each driver makes some internal check to ensure that
the selected states of CPUs in the same domain are compatibles.

>
> If:
>
> CLUSTER_RETENTION_0  - index 2
> CLUSTER_RETENTION_1  - index 3
>
> Cleraly if some CPUs are in index 3 and some in 2, 2 must be chosen.
>
> This demotion is easy to carry out with the information in the bindings.
> If a state affect power domains that span multiples CPUs (and not only
> CPUs....), all CPUs (+ devices) must be in that state (or "higher") for it
> to be valid.

So it implies that we assume a decreasing compatibility so that if a
cpu is in index N but share power domain with other cpus in state n-3
then we select n-3 for all cpus ? My point is that I'm not sure that
this always apply but no simple example is coming for the moment in my
mind :-)

>
> If not, demotion should take place (or put it differently that state
> becomes invalid).
>
> A LUT should be sufficient for a CPU to detect what it has to do upon
> state entry.
>
> I will give it more thought but I think the information in the bindings
> is still sufficient to pull this off.
>
> I am a bit concerned about the power domains representation in the DT, I
> will think more about this too and keep you posted.

Thanks
Vincent

>
> Thanks,
> Lorenzo
>
>>
>> Regards,
>> Vincent
>>
>> >
>> > Thank you !!
>> > Lorenzo
>> >
>> >> Then, IMHO, the flat description below is clearer and remove the
>> >> duplicated description that you mention previously
>> >>
>> >> Regards,
>> >> Vincent
>> >>
>> >> >
>> >> > Thoughts very appreciated, thanks.
>> >> >
>> >> > Lorenzo
>> >> >
>> >> > idle-states {
>> >> >        entry-method = "arm,psci-cpu-suspend";
>> >> >
>> >> >         CPU_RETENTION_0: cpu-retention-0 {
>> >> >                        compatible = "arm,idle-state";
>> >> >                        cache-state-retained;
>> >> >                        entry-method-param = <0x0010000>;
>> >> >                        entry-latency-us = <20>;
>> >> >                        exit-latency-us = <40>;
>> >> >                        min-residency-us = <30>;
>> >> >                        power-domains = <&pd_cores 0>,
>> >> >                                        <&pd_cores 1>,
>> >> >                                        <&pd_cores 2>,
>> >> >                                        <&pd_cores 3>,
>> >> >         };
>> >> >
>> >> >         CPU_SLEEP_0: cpu-sleep-0 {
>> >> >                        /* cpu sleep */
>> >> >                        compatible = "arm,idle-state";
>> >> >                        entry-method-param = <0x0010000>;
>> >> >                        entry-latency-us = <250>;
>> >> >                        exit-latency-us = <500>;
>> >> >                        min-residency-us = <350>;
>> >> >                        power-domains = <&pd_cores 0>,
>> >> >                                        <&pd_cores 1>,
>> >> >                                        <&pd_cores 2>,
>> >> >                                        <&pd_cores 3>,
>> >> >         };
>> >> >
>> >> >         CPU_SLEEP_1: cpu-sleep-1 {
>> >> >                        /* cpu sleep */
>> >> >                        compatible = "arm,idle-state";
>> >> >                        entry-method-param = <0x0010000>;
>> >> >                        entry-latency-us = <250>;
>> >> >                        exit-latency-us = <500>;
>> >> >                        min-residency-us = <350>;
>> >> >                                        <&pd_cores 4>,
>> >> >                                        <&pd_cores 5>,
>> >> >                                        <&pd_cores 6>,
>> >> >                                        <&pd_cores 7>;
>> >> >         };
>> >> >
>> >> >         CLUSTER_RETENTION_0: cluster-retention-0 {
>> >> >                compatible = "arm,idle-state";
>> >> >                logic-state-retained;
>> >> >                cache-state-retained;
>> >> >                entry-method-param = <0x1010000>;
>> >> >                entry-latency-us = <50>;
>> >> >                exit-latency-us = <800>;
>> >> >                min-residency-us = <2400>;
>> >> >                power-domains = <&pd_clusters 0>;
>> >> >                substates = <&CPU_SLEEP_0>;
>> >> >         };
>> >> >
>> >> >         CLUSTER_SLEEP_0: cluster-sleep-0 {
>> >> >                compatible = "arm,idle-state";
>> >> >                entry-method-param = <0x1010000>;
>> >> >                entry-latency-us = <600>;
>> >> >                exit-latency-us = <1100>;
>> >> >                min-residency-us = <2700>;
>> >> >                power-domains = <&pd_clusters 0>;
>> >> >                substates = <&CPU_SLEEP_0>;
>> >> >         };
>> >> >
>> >> >         CLUSTER_SLEEP_1: cluster-sleep-1 {
>> >> >                compatible = "arm,idle-state";
>> >> >                entry-method-param = <0x1010000>;
>> >> >                entry-latency-us = <600>;
>> >> >                exit-latency-us = <1100>;
>> >> >                min-residency-us = <2700>;
>> >> >                power-domains = <&pd_clusters 1>;
>> >> >                substates = <&CPU_SLEEP_1>;
>> >> >         };
>> >> >
>> >> >         SYSTEM_SLEEP_0: system-sleep-0 {
>> >> >                compatible = "arm,idle-state";
>> >> >                entry-method-param = <0x2010000>;
>> >> >                entry-latency-us = <6000>;
>> >> >                exit-latency-us = <10000>;
>> >> >                min-residency-us = <30000>;
>> >> >                power-domains = <&pd_system 0>;
>> >> >                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
>> >> >         };
>> >> > };
>> >> >
>> >>
>> >
>>
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-08  9:11               ` Vincent Guittot
  0 siblings, 0 replies; 26+ messages in thread
From: Vincent Guittot @ 2014-04-08  9:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 7 April 2014 20:03, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Mon, Apr 07, 2014 at 04:34:49PM +0100, Vincent Guittot wrote:
>> On 7 April 2014 16:36, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> > On Mon, Apr 07, 2014 at 01:25:17PM +0100, Vincent Guittot wrote:
>> >> On 4 April 2014 17:56, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
>> >> > [replying to self, since I have a query]
>> >> >
>> >> > [...]
>> >> >
>> >> >> +===========================================
>> >> >> +4 - Examples
>> >> >> +===========================================
>> >> >> +
>> >> >> +Example 1 (ARM 64-bit, 16-cpu system):
>> >> >> +
>> >> >> +pd_clusters: power-domain-clusters at 80002000 {
>> >> >> +       compatible = "arm,power-controller";
>> >> >> +       reg = <0x0 0x80002000 0x0 0x1000>;
>> >> >> +       #power-domain-cells = <1>;
>> >> >> +       #address-cells = <2>;
>> >> >> +       #size-cells = <2>;
>> >> >> +
>> >> >> +       pd_cores: power-domain-cores at 80000000 {
>> >> >> +               compatible = "arm,power-controller";
>> >> >> +               reg = <0x0 0x80000000 0x0 0x1000>;
>> >> >> +               #power-domain-cells = <1>;
>> >> >> +       };
>> >> >> +};
>> >> >> +
>> >> >> +cpus {
>> >> >> +       #size-cells = <0>;
>> >> >> +       #address-cells = <2>;
>> >> >> +
>> >> >> +       idle-states {
>> >> >> +               entry-method = "arm,psci-cpu-suspend";
>> >> >> +
>> >> >> +               CLUSTER_RETENTION_0: cluster-retention-0 {
>> >> >> +                       compatible = "arm,idle-state";
>> >> >> +                       index = <2>;
>> >> >> +                       logic-state-retained;
>> >> >> +                       cache-state-retained;
>> >> >> +                       entry-method-param = <0x1010000>;
>> >> >> +                       entry-latency-us = <50>;
>> >> >> +                       exit-latency-us = <100>;
>> >> >> +                       min-residency-us = <250>;
>> >> >> +                       power-domains = <&pd_clusters 0>;
>> >> >> +                       CPU_RETENTION_0_0: cpu-retention-0 {
>> >> >> +                               compatible = "arm,idle-state";
>> >> >> +                               index = <0>;
>> >> >> +                               cache-state-retained;
>> >> >> +                               entry-method-param = <0x0010000>;
>> >> >> +                               entry-latency-us = <20>;
>> >> >> +                               exit-latency-us = <40>;
>> >> >> +                               min-residency-us = <30>;
>> >> >> +                               power-domains = <&pd_cores 0>,
>> >> >> +                                               <&pd_cores 1>,
>> >> >> +                                               <&pd_cores 2>,
>> >> >> +                                               <&pd_cores 3>,
>> >> >> +                                               <&pd_cores 4>,
>> >> >> +                                               <&pd_cores 5>,
>> >> >> +                                               <&pd_cores 6>,
>> >> >> +                                               <&pd_cores 7>;
>> >> >> +                       };
>> >> >> +               };
>> >> >> +
>> >> >> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
>> >> >> +                       compatible = "arm,idle-state";
>> >> >> +                       index = <3>;
>> >> >> +                       entry-method-param = <0x1010000>;
>> >> >> +                       entry-latency-us = <600>;
>> >> >> +                       exit-latency-us = <1100>;
>> >> >> +                       min-residency-us = <2700>;
>> >> >> +                       power-domains = <&pd_clusters 0>;
>> >> >> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
>> >> >> +                               /* cpu sleep */
>> >> >> +                               compatible = "arm,idle-state";
>> >> >> +                               index = <1>;
>> >> >> +                               entry-method-param = <0x0010000>;
>> >> >> +                               entry-latency-us = <250>;
>> >> >> +                               exit-latency-us = <500>;
>> >> >> +                               min-residency-us = <350>;
>> >> >> +                               power-domains = <&pd_cores 0>,
>> >> >> +                                               <&pd_cores 1>,
>> >> >> +                                               <&pd_cores 2>,
>> >> >> +                                               <&pd_cores 3>,
>> >> >> +                                               <&pd_cores 4>,
>> >> >> +                                               <&pd_cores 5>,
>> >> >> +                                               <&pd_cores 6>,
>> >> >> +                                               <&pd_cores 7>;
>> >> >> +                       };
>> >> >> +               };
>> >> >
>> >> > I noticed while developing the CPUidle generic driver, that by using this
>> >> > representation I might end up requiring duplicated states.
>> >> >
>> >> > For instance, a cluster-retention state and a cluster-sleep state might
>> >> > want to have cpu-sleep state as substate, and this would require an
>> >> > idle state node duplication.
>> >> >
>> >> > I think it is better to have a single flat (and ordered...that would
>> >> > kill two birds with one stone) list of nodes in the idle-states node and
>> >> > every state might have a list of phandles to subnodes (substates), something
>> >> > like the following example.
>> >> >
>> >> > This simplifies parsing  and I think it solves the last issue I
>> >> > came across (the need for duplicate states - in the bindings below,
>> >> > CPU_SLEEP_0 is a substate of both CLUSTER_RETENTION_0 and
>> >> > CLUSTER_SLEEP_0, through phandles).
>> >>
>> >> Hi Lorenzo,
>> >>
>> >> You explanation above has triggered a question. You writes:
>> >> CPU_SLEEP_0 is a substate of CLUSTER_RETENTION_0 but i would have say
>> >> that both CPU_SLEEP_0 and CPU_RETENTION_0 are substates of
>> >> CLUSTER_RETENTION_0. I mean that if cpus are either in retention mode
>> >> OR in  sleep mode, you can enter the CLUSTER_RETENTION_0 state (you
>> >> can have some in sleep mode and other in retention of course)
>> >> I'm wondering how this OR  will be described.
>> >
>> > We need another state (because that's what happens in HW right ?), so we
>> > describe it (obviously having different latencies):
>> >
>> >
>> >         CLUSTER_RETENTION_1: cluster-retention-1 {
>> >                 compatible = "arm,idle-state";
>> >                 logic-state-retained;
>> >                 cache-state-retained;
>> >                 entry-method-param = <0x1010000>;
>> >                 entry-latency-us = <50>;
>> >                 exit-latency-us = <700>;
>> >                 min-residency-us = <2000>;
>> >                 power-domains = <&pd_clusters 0>;
>> >                 substates = <&CPU_RETENTION_0>;
>> >          };
>> >
>> > Using phandles all state combinations are now possible, with no state
>> > duplication.
>> >
>> > State above is entered when all CPUs are in retention mode and thanks
>> > to the phandle the kernel knows what has to be done as far as each
>> > CPU is concerned. The beauty of this approach is that for every state,
>> > it is well defined what has to be done for the respective power domain
>> > (eg state above, cache is retained. All caches in <&pd_clusters 0> are
>> > retained. Then we follow the substates, and take action according to
>> > the substate propertes and respective power domain).
>> >
>> > Does this make sense ? I can't find fault with this semantics, but
>> > please let me know if you do.
>>
>>
>> So we will have some cpus of the cluster in CLUSTER_RETENTION_1 state
>> and other cpus of the same cluster in CLUSTER_RETENTION_0 depending of
>> the power state of the cpu part but for the same power state of common
>> part of the cluster.
>> How does the driver know that both power states are compatible ? I
>> mean how the last cpu will know that it can put the cluster in
>> retention state because all the other cpus of the cluster are in a
>> compatible state ?
>
> Short answer: the power domain hierarchy will define what CPUs are in what
> power domain. For states that encompass multiple cpus for them to be valid,
> we just use the lowest common index approach (I am talking about index in the
> idle state order - which, if the list is flat and ordered in terms of power
> savings is easy to define).
>
> That's how idle works today, I am not adding anything new.

I agree but today each driver makes some internal check to ensure that
the selected states of CPUs in the same domain are compatibles.

>
> If:
>
> CLUSTER_RETENTION_0  - index 2
> CLUSTER_RETENTION_1  - index 3
>
> Cleraly if some CPUs are in index 3 and some in 2, 2 must be chosen.
>
> This demotion is easy to carry out with the information in the bindings.
> If a state affect power domains that span multiples CPUs (and not only
> CPUs....), all CPUs (+ devices) must be in that state (or "higher") for it
> to be valid.

So it implies that we assume a decreasing compatibility so that if a
cpu is in index N but share power domain with other cpus in state n-3
then we select n-3 for all cpus ? My point is that I'm not sure that
this always apply but no simple example is coming for the moment in my
mind :-)

>
> If not, demotion should take place (or put it differently that state
> becomes invalid).
>
> A LUT should be sufficient for a CPU to detect what it has to do upon
> state entry.
>
> I will give it more thought but I think the information in the bindings
> is still sufficient to pull this off.
>
> I am a bit concerned about the power domains representation in the DT, I
> will think more about this too and keep you posted.

Thanks
Vincent

>
> Thanks,
> Lorenzo
>
>>
>> Regards,
>> Vincent
>>
>> >
>> > Thank you !!
>> > Lorenzo
>> >
>> >> Then, IMHO, the flat description below is clearer and remove the
>> >> duplicated description that you mention previously
>> >>
>> >> Regards,
>> >> Vincent
>> >>
>> >> >
>> >> > Thoughts very appreciated, thanks.
>> >> >
>> >> > Lorenzo
>> >> >
>> >> > idle-states {
>> >> >        entry-method = "arm,psci-cpu-suspend";
>> >> >
>> >> >         CPU_RETENTION_0: cpu-retention-0 {
>> >> >                        compatible = "arm,idle-state";
>> >> >                        cache-state-retained;
>> >> >                        entry-method-param = <0x0010000>;
>> >> >                        entry-latency-us = <20>;
>> >> >                        exit-latency-us = <40>;
>> >> >                        min-residency-us = <30>;
>> >> >                        power-domains = <&pd_cores 0>,
>> >> >                                        <&pd_cores 1>,
>> >> >                                        <&pd_cores 2>,
>> >> >                                        <&pd_cores 3>,
>> >> >         };
>> >> >
>> >> >         CPU_SLEEP_0: cpu-sleep-0 {
>> >> >                        /* cpu sleep */
>> >> >                        compatible = "arm,idle-state";
>> >> >                        entry-method-param = <0x0010000>;
>> >> >                        entry-latency-us = <250>;
>> >> >                        exit-latency-us = <500>;
>> >> >                        min-residency-us = <350>;
>> >> >                        power-domains = <&pd_cores 0>,
>> >> >                                        <&pd_cores 1>,
>> >> >                                        <&pd_cores 2>,
>> >> >                                        <&pd_cores 3>,
>> >> >         };
>> >> >
>> >> >         CPU_SLEEP_1: cpu-sleep-1 {
>> >> >                        /* cpu sleep */
>> >> >                        compatible = "arm,idle-state";
>> >> >                        entry-method-param = <0x0010000>;
>> >> >                        entry-latency-us = <250>;
>> >> >                        exit-latency-us = <500>;
>> >> >                        min-residency-us = <350>;
>> >> >                                        <&pd_cores 4>,
>> >> >                                        <&pd_cores 5>,
>> >> >                                        <&pd_cores 6>,
>> >> >                                        <&pd_cores 7>;
>> >> >         };
>> >> >
>> >> >         CLUSTER_RETENTION_0: cluster-retention-0 {
>> >> >                compatible = "arm,idle-state";
>> >> >                logic-state-retained;
>> >> >                cache-state-retained;
>> >> >                entry-method-param = <0x1010000>;
>> >> >                entry-latency-us = <50>;
>> >> >                exit-latency-us = <800>;
>> >> >                min-residency-us = <2400>;
>> >> >                power-domains = <&pd_clusters 0>;
>> >> >                substates = <&CPU_SLEEP_0>;
>> >> >         };
>> >> >
>> >> >         CLUSTER_SLEEP_0: cluster-sleep-0 {
>> >> >                compatible = "arm,idle-state";
>> >> >                entry-method-param = <0x1010000>;
>> >> >                entry-latency-us = <600>;
>> >> >                exit-latency-us = <1100>;
>> >> >                min-residency-us = <2700>;
>> >> >                power-domains = <&pd_clusters 0>;
>> >> >                substates = <&CPU_SLEEP_0>;
>> >> >         };
>> >> >
>> >> >         CLUSTER_SLEEP_1: cluster-sleep-1 {
>> >> >                compatible = "arm,idle-state";
>> >> >                entry-method-param = <0x1010000>;
>> >> >                entry-latency-us = <600>;
>> >> >                exit-latency-us = <1100>;
>> >> >                min-residency-us = <2700>;
>> >> >                power-domains = <&pd_clusters 1>;
>> >> >                substates = <&CPU_SLEEP_1>;
>> >> >         };
>> >> >
>> >> >         SYSTEM_SLEEP_0: system-sleep-0 {
>> >> >                compatible = "arm,idle-state";
>> >> >                entry-method-param = <0x2010000>;
>> >> >                entry-latency-us = <6000>;
>> >> >                exit-latency-us = <10000>;
>> >> >                min-residency-us = <30000>;
>> >> >                power-domains = <&pd_system 0>;
>> >> >                substates = <&CLUSTER_SLEEP_0>, <&CLUSTER_SLEEP_1>;
>> >> >         };
>> >> > };
>> >> >
>> >>
>> >
>>
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
  2014-03-18 11:28   ` Lorenzo Pieralisi
@ 2014-04-29 10:56     ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-29 10:56 UTC (permalink / raw)
  To: devicetree
  Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
	Russell King, Sebastian Capella, Nicolas Pitre, Daniel Lezcano,
	linux-arm-kernel, grant.likely, Dave P Martin,
	Charles Garcia-Tobin, Kevin Hilman, linux-pm, Kumar Gala,
	Rob Herring, Vincent Guittot, Antti Miettinen,
	Peter De Schrijver, Stephen Boyd

[replying to self, further query]

On Tue, Mar 18, 2014 at 11:28:52AM +0000, Lorenzo Pieralisi wrote:
> ARM based platforms implement a variety of power management schemes that
> allow processors to enter idle states at run-time.
> The parameters defining these idle states vary on a per-platform basis forcing
> the OS to hardcode the state parameters in platform specific static tables
> whose size grows as the number of platforms supported in the kernel increases
> and hampers device drivers standardization.
> 
> Therefore, this patch aims at standardizing idle state device tree bindings for
> ARM platforms. Bindings define idle state parameters inclusive of entry methods
> and state latencies, to allow operating systems to retrieve the configuration
> entries from the device tree and initialize the related power management
> drivers, paving the way for common code in the kernel to deal with idle
> states and removing the need for static data in current and previous kernel
> versions.
> 
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

I was thinking of streamlining these bindings, in particular removing the
power-domain dependency (on cpu, cache, and idle states) waiting for the
dust to settle (and code in the kernel showing that's what we really
need).

The current generic CPU idle code does not require all this complexity:

http://www.spinics.net/lists/devicetree/msg29816.html

and I think, now that we've debated the pros and cons of power domains,
we will be able to add the required properties in the future, they are
optional by the way, and I do not think it is a problem to wait.

Is it ok to remove properties knowing that they can be added as optional
later on ? Or we do want them to be there from the beginning ? That's
the gist of this discussion and the reason I tried to be as comprehensive as
possible.

So, if nobody complains:

- I am removing power domains from cpu, cache and idle states bindings
- I am removing the index property from idle states as requested
- I will reword (again) min-residency-us
- I will use min-residency-us+exit-latency-us to sort the states
- I will repost the generic CPU idle code and streamlined bindings
  together to ease review
- I am NOT adding a substates property, since it is not needed at the
  moment (ie when using PSCI as entry method)
- We have to understand what to do with cache bindings (with power domain
  properties removed) since there is a series depending on them
  https://lkml.org/lkml/2014/4/4/436

Thoughts would be very appreciated at this point.

Thanks for your help,
Lorenzo

> ---
>  Documentation/devicetree/bindings/arm/cpus.txt     |  18 +
>  .../devicetree/bindings/arm/idle-states.txt        | 771 +++++++++++++++++++++
>  2 files changed, 789 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
> index 9130435..79a1d9b 100644
> --- a/Documentation/devicetree/bindings/arm/cpus.txt
> +++ b/Documentation/devicetree/bindings/arm/cpus.txt
> @@ -191,6 +191,19 @@ nodes to be present and contain the properties described below.
>                           property identifying a 64-bit zero-initialised
>                           memory location.
> 
> +       - cpu-idle-states
> +               Usage: Optional
> +               Value type: <prop-encoded-array>
> +               Definition:
> +                       # List of phandles to idle state nodes supported
> +                         by this cpu [1].
> +
> +       - power-domain
> +               Usage: Optional
> +               Value type: <prop-encoded-array>
> +               Definition: A phandle and power domain specifier as defined by
> +                           bindings of power domain specified by [2].
> +
>  Example 1 (dual-cluster big.LITTLE system 32-bit):
> 
>         cpus {
> @@ -382,3 +395,8 @@ cpus {
>                 cpu-release-addr = <0 0x20000000>;
>         };
>  };
> +
> +[1] ARM Linux kernel documentation - idle states bindings
> +    Documentation/devicetree/bindings/arm/idle-states.txt
> +[2] Kernel documentation - power domain bindings
> +    Documentation/devicetree/bindings/power/power_domain.txt
> diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt
> new file mode 100644
> index 0000000..fee176d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/idle-states.txt
> @@ -0,0 +1,771 @@
> +==========================================
> +ARM idle states binding description
> +==========================================
> +
> +==========================================
> +1 - Introduction
> +==========================================
> +
> +ARM systems contain HW capable of managing power consumption dynamically,
> +where cores can be put in different low-power states (ranging from simple
> +wfi to power gating) according to OSPM policies. The CPU states representing
> +the range of dynamic idle states that a processor can enter at run-time, can be
> +specified through device tree bindings representing the parameters required
> +to enter/exit specific idle states on a given processor.
> +
> +According to the Server Base System Architecture document (SBSA, [4]), the
> +power states an ARM CPU can be put into are identified by the following list:
> +
> +- Running
> +- Idle_standby
> +- Idle_retention
> +- Sleep
> +- Off
> +
> +The power states described in the SBSA document define the basic CPU states on
> +top of which ARM platforms implement power management schemes that allow an OS
> +PM implementation to put the processor in different idle states (which include
> +states listed above; "off" state is not an idle state since it does not have
> +wake-up capabilities, hence it is not considered in this document).
> +
> +Idle state parameters (eg entry latency) are platform specific and need to be
> +characterized with bindings that provide the required information to OSPM
> +code so that it can build the required tables and use them at runtime.
> +
> +The device tree binding definition for ARM idle states is the subject of this
> +document.
> +
> +===========================================
> +2 - idle-states node
> +===========================================
> +
> +ARM processor idle states are defined within the idle-states node, which is
> +a direct child of the cpus node and provides a container where the processor
> +idle states, defined as device tree nodes, are listed.
> +
> +- idle-states node
> +
> +       Usage: Optional - On ARM systems, is a container of processor idle
> +                         states nodes. If the system does not provide CPU
> +                         power management capabilities or the processor just
> +                         supports idle_standby an idle-states node is not
> +                         required.
> +
> +       Description: idle-states node is a container node, where its
> +                    subnodes describe the CPU idle states.
> +
> +       Node name must be "idle-states".
> +
> +       The idle-states node's parent node must be the cpus node.
> +
> +       The idle-states node's child nodes can be:
> +
> +       - one or more state nodes
> +
> +       Any other configuration is considered invalid.
> +
> +       An idle-states node defines the following properties:
> +
> +       - entry-method
> +               Usage: Required
> +               Value type: <stringlist>
> +               Definition: Describes the method by which a CPU enters the
> +                           idle states. This property is required and must be
> +                           one of:
> +
> +                           - "arm,psci"
> +                             ARM PSCI firmware interface [3].
> +
> +                           - "[vendor],[method]"
> +                             An implementation dependent string with
> +                             format "vendor,method", where vendor is a string
> +                             denoting the name of the manufacturer and
> +                             method is a string specifying the mechanism
> +                             used to enter the idle state.
> +
> +The nodes describing the idle states (state) can only be defined within the
> +idle-states node.
> +
> +Any other configuration is consider invalid and therefore must be ignored.
> +
> +===========================================
> +3 - state node
> +===========================================
> +
> +A state node represents an idle state description and must be defined as
> +follows:
> +
> +- state node
> +
> +       Description: must be child of either the idle-states node or
> +                    a state node.
> +
> +       The state node name shall follow standard device tree naming
> +       rules ([6], 2.2.1 "Node names"), in particular state nodes which
> +       are siblings within a single common parent must be given a unique name.
> +
> +       The idle state entered by executing the wfi instruction (idle_standby
> +       SBSA,[4][5]) is considered standard on all ARM platforms and therefore
> +       must not be listed.
> +
> +       A state node can contain state child nodes. A state node with
> +       children represents a hierarchical state, which is a superset of
> +       the child states.
> +
> +       A state node defines the following properties:
> +
> +       - compatible
> +               Usage: Required
> +               Value type: <stringlist>
> +               Definition: Must be "arm,idle-state".
> +
> +       - index
> +               Usage: Required
> +               Value type: <u32>
> +               Definition: It represents the idle state index.
> +                           The index must be given an increasing
> +                           value = {0, 1, ....}, starting from 0, with higher
> +                           values implying less power consumption.
> +                           Indices must be unique as seen from a cpu
> +                           perspective, ie phandles in the cpu nodes [1]
> +                           cpu-idle-states array property are not allowed to
> +                           point at idle state nodes having the same index
> +                           value.
> +
> +       - logic-state-retained
> +               Usage: See definition
> +               Value type: <none>
> +               Definition: if present logic is retained on state entry,
> +                           otherwise it is lost.
> +
> +       - cache-state-retained
> +               Usage: See definition
> +               Value type: <none>
> +               Definition: if present cache memory is retained on state entry,
> +                           otherwise it is lost.
> +
> +       - entry-method-param
> +               Usage: See definition.
> +               Value type: <u32>
> +               Definition: Depends on the idle-states node entry-method
> +                           property value. Refer to the entry-method bindings
> +                           for this property value definition.
> +
> +       - entry-latency-us
> +               Usage: Required
> +               Value type: <prop-encoded-array>
> +               Definition: u32 value representing worst case latency
> +                           in microseconds required to enter the idle state.
> +
> +       - exit-latency-us
> +               Usage: Required
> +               Value type: <prop-encoded-array>
> +               Definition: u32 value representing worst case latency
> +                           in microseconds required to exit the idle state.
> +
> +       - min-residency-us
> +               Usage: Required
> +               Value type: <prop-encoded-array>
> +               Definition: u32 value representing time in microseconds
> +                           required for the CPU to be in the idle state to
> +                           guarantee power savings maximization.
> +
> +       - power-domains
> +               Usage: Optional
> +               Value type: <prop-encoded-array>
> +               Definition: List of phandle and power domain specifiers ([2])
> +                           describing the power domains that are affected by
> +                           the idle state entry. All devices whose
> +                           power-domains property contains entries referring
> +                           to one of the power domains listed in this
> +                           property are affected by the idle state entry.
> +
> +===========================================
> +4 - Examples
> +===========================================
> +
> +Example 1 (ARM 64-bit, 16-cpu system):
> +
> +pd_clusters: power-domain-clusters@80002000 {
> +       compatible = "arm,power-controller";
> +       reg = <0x0 0x80002000 0x0 0x1000>;
> +       #power-domain-cells = <1>;
> +       #address-cells = <2>;
> +       #size-cells = <2>;
> +
> +       pd_cores: power-domain-cores@80000000 {
> +               compatible = "arm,power-controller";
> +               reg = <0x0 0x80000000 0x0 0x1000>;
> +               #power-domain-cells = <1>;
> +       };
> +};
> +
> +cpus {
> +       #size-cells = <0>;
> +       #address-cells = <2>;
> +
> +       idle-states {
> +               entry-method = "arm,psci-cpu-suspend";
> +
> +               CLUSTER_RETENTION_0: cluster-retention-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <2>;
> +                       logic-state-retained;
> +                       cache-state-retained;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <50>;
> +                       exit-latency-us = <100>;
> +                       min-residency-us = <250>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_RETENTION_0_0: cpu-retention-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               cache-state-retained;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <20>;
> +                               exit-latency-us = <40>;
> +                               min-residency-us = <30>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>,
> +                                               <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };
> +
> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <3>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <600>;
> +                       exit-latency-us = <1100>;
> +                       min-residency-us = <2700>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> +                               /* cpu sleep */
> +                               compatible = "arm,idle-state";
> +                               index = <1>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <250>;
> +                               exit-latency-us = <500>;
> +                               min-residency-us = <350>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>,
> +                                               <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };
> +               CLUSTER_RETENTION_1: cluster-retention-1 {
> +                       compatible = "arm,idle-state";
> +                       index = <2>;
> +                       logic-state-retained;
> +                       cache-state-retained;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <50>;
> +                       exit-latency-us = <100>;
> +                       min-residency-us = <270>;
> +                       power-domains = <&pd_clusters 1>;
> +                       CPU_RETENTION_1_0: cpu-retention-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               cache-state-retained;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <20>;
> +                               exit-latency-us = <40>;
> +                               min-residency-us = <30>;
> +                               power-domains = <&pd_cores 8>,
> +                                               <&pd_cores 9>,
> +                                               <&pd_cores 10>,
> +                                               <&pd_cores 11>,
> +                                               <&pd_cores 12>,
> +                                               <&pd_cores 13>,
> +                                               <&pd_cores 14>,
> +                                               <&pd_cores 15>;
> +                       };
> +               };
> +
> +               CLUSTER_SLEEP_1: cluster-sleep-1 {
> +                       compatible = "arm,idle-state";
> +                       index = <3>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <500>;
> +                       exit-latency-us = <1200>;
> +                       min-residency-us = <3500>;
> +                       power-domains = <&pd_clusters 1>;
> +                       CPU_SLEEP_1_0: cpu-sleep-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <1>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <70>;
> +                               exit-latency-us = <100>;
> +                               min-residency-us = <100>;
> +                               power-domains = <&pd_cores 8>,
> +                                               <&pd_cores 9>,
> +                                               <&pd_cores 10>,
> +                                               <&pd_cores 11>,
> +                                               <&pd_cores 12>,
> +                                               <&pd_cores 13>,
> +                                               <&pd_cores 14>,
> +                                               <&pd_cores 15>;
> +                       };
> +               };
> +       };
> +
> +       CPU0: cpu@0 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x0>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_0>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_0: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 0>;
> +               };
> +               L2_0: l2-cache {
> +                       compatible = "arm,arch-cache";
> +                       power-domain = <&pd_clusters 0>;
> +               };
> +       };
> +
> +       CPU1: cpu@1 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x1>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_1>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_1: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 1>;
> +               };
> +       };
> +
> +       CPU2: cpu@100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x100>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_2>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_2: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 2>;
> +               };
> +       };
> +
> +       CPU3: cpu@101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x101>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_3>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_3: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 3>;
> +               };
> +       };
> +
> +       CPU4: cpu@10000 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x10000>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_4>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_4: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 4>;
> +               };
> +       };
> +
> +       CPU5: cpu@10001 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x10001>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_5>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_5: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 5>;
> +               };
> +       };
> +
> +       CPU6: cpu@10100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x10100>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_6>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_6: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 6>;
> +               };
> +       };
> +
> +       CPU7: cpu@10101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x10101>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_7>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_7: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 7>;
> +               };
> +       };
> +
> +       CPU8: cpu@100000000 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x0>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_8>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_8: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 8>;
> +               };
> +               L2_1: l2-cache {
> +                       compatible = "arm,arch-cache";
> +                       power-domain = <&pd_clusters 1>;
> +               };
> +       };
> +
> +       CPU9: cpu@100000001 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x1>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_9>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_9: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 9>;
> +               };
> +       };
> +
> +       CPU10: cpu@100000100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x100>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_10>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_10: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 10>;
> +               };
> +       };
> +
> +       CPU11: cpu@100000101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x101>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_11>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_11: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 11>;
> +               };
> +       };
> +
> +       CPU12: cpu@100010000 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x10000>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_12>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_12: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 12>;
> +               };
> +       };
> +
> +       CPU13: cpu@100010001 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x10001>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_13>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_13: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 13>;
> +               };
> +       };
> +
> +       CPU14: cpu@100010100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x10100>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_14>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_14: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 14>;
> +               };
> +       };
> +
> +       CPU15: cpu@100010101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x10101>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_15>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_15: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 15>;
> +               };
> +       };
> +};
> +
> +Example 2 (ARM 32-bit, 8-cpu system, two clusters):
> +
> +pd_clusters: power-domain-clusters@80002000 {
> +       compatible = "arm,power-controller";
> +       reg = <0x80002000 0x1000>;
> +       #power-domain-cells = <1>;
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       pd_cores: power-domain-cores@80000000 {
> +               compatible = "arm,power-controller";
> +               reg = <0x80000000 0x1000>;
> +               #power-domain-cells = <1>;
> +       };
> +};
> +
> +cpus {
> +       #size-cells = <0>;
> +       #address-cells = <1>;
> +
> +       idle-states {
> +               entry-method = "arm,psci-cpu-suspend";
> +
> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <1>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <1000>;
> +                       exit-latency-us = <1500>;
> +                       min-residency-us = <1500>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <400>;
> +                               exit-latency-us = <500>;
> +                               min-residency-us = <300>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>;
> +                       };
> +               };
> +
> +               CLUSTER_SLEEP_1: cluster-sleep-1 {
> +                       compatible = "arm,idle-state";
> +                       index = <1>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <800>;
> +                       exit-latency-us = <2000>;
> +                       min-residency-us = <6500>;
> +                       power-domains = <&pd_clusters 1>;
> +                       CPU_SLEEP_1_0: cpu-sleep-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <300>;
> +                               exit-latency-us = <500>;
> +                               min-residency-us = <500>;
> +                               power-domains = <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };
> +       };
> +
> +       CPU0: cpu@0 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a15";
> +               reg = <0x0>;
> +               next-level-cache = <&L1_0>;
> +               cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
> +               L1_0: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 0>;
> +               };
> +               L2_0: l2-cache {
> +                       compatible = "arm,arch-cache";
> +                       power-domain = <&pd_clusters 0>;
> +               };
> +       };
> +
> +       CPU1: cpu@1 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a15";
> +               reg = <0x1>;
> +               next-level-cache = <&L1_1>;
> +               cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
> +               L1_1: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 1>;
> +               };
> +       };
> +
> +       CPU2: cpu@2 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a15";
> +               reg = <0x2>;
> +               next-level-cache = <&L1_2>;
> +               cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
> +               L1_2: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 2>;
> +               };
> +       };
> +
> +       CPU3: cpu@3 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a15";
> +               reg = <0x3>;
> +               next-level-cache = <&L1_3>;
> +               cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
> +               L1_3: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 3>;
> +               };
> +       };
> +
> +       CPU4: cpu@100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a7";
> +               reg = <0x100>;
> +               next-level-cache = <&L1_4>;
> +               cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
> +               L1_4: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 4>;
> +               };
> +               L2_1: l2-cache {
> +                       compatible = "arm,arch-cache";
> +                       power-domain = <&pd_clusters 1>;
> +               };
> +       };
> +
> +       CPU5: cpu@101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a7";
> +               reg = <0x101>;
> +               next-level-cache = <&L1_5>;
> +               cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
> +               L1_5: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 5>;
> +               };
> +       };
> +
> +       CPU6: cpu@102 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a7";
> +               reg = <0x102>;
> +               next-level-cache = <&L1_6>;
> +               cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
> +               L1_6: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 6>;
> +               };
> +       };
> +
> +       CPU7: cpu@103 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a7";
> +               reg = <0x103>;
> +               next-level-cache = <&L1_7>;
> +               cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
> +               L1_7: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 7>;
> +               };
> +       };
> +};
> +
> +===========================================
> +4 - References
> +===========================================
> +
> +[1] ARM Linux Kernel documentation - CPUs bindings
> +    Documentation/devicetree/bindings/arm/cpus.txt
> +
> +[2] ARM Linux Kernel documentation - power domain bindings
> +    Documentation/devicetree/bindings/power/power_domain.txt
> +
> +[3] ARM Linux Kernel documentation - PSCI bindings
> +    Documentation/devicetree/bindings/arm/psci.txt
> +
> +[4] ARM Server Base System Architecture (SBSA)
> +    http://infocenter.arm.com/help/index.jsp
> +
> +[5] ARM Architecture Reference Manuals
> +    http://infocenter.arm.com/help/index.jsp
> +
> +[6] ePAPR standard
> +    https://www.power.org/documentation/epapr-version-1-1/
> --
> 1.8.4
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings
@ 2014-04-29 10:56     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 26+ messages in thread
From: Lorenzo Pieralisi @ 2014-04-29 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

[replying to self, further query]

On Tue, Mar 18, 2014 at 11:28:52AM +0000, Lorenzo Pieralisi wrote:
> ARM based platforms implement a variety of power management schemes that
> allow processors to enter idle states at run-time.
> The parameters defining these idle states vary on a per-platform basis forcing
> the OS to hardcode the state parameters in platform specific static tables
> whose size grows as the number of platforms supported in the kernel increases
> and hampers device drivers standardization.
> 
> Therefore, this patch aims at standardizing idle state device tree bindings for
> ARM platforms. Bindings define idle state parameters inclusive of entry methods
> and state latencies, to allow operating systems to retrieve the configuration
> entries from the device tree and initialize the related power management
> drivers, paving the way for common code in the kernel to deal with idle
> states and removing the need for static data in current and previous kernel
> versions.
> 
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

I was thinking of streamlining these bindings, in particular removing the
power-domain dependency (on cpu, cache, and idle states) waiting for the
dust to settle (and code in the kernel showing that's what we really
need).

The current generic CPU idle code does not require all this complexity:

http://www.spinics.net/lists/devicetree/msg29816.html

and I think, now that we've debated the pros and cons of power domains,
we will be able to add the required properties in the future, they are
optional by the way, and I do not think it is a problem to wait.

Is it ok to remove properties knowing that they can be added as optional
later on ? Or we do want them to be there from the beginning ? That's
the gist of this discussion and the reason I tried to be as comprehensive as
possible.

So, if nobody complains:

- I am removing power domains from cpu, cache and idle states bindings
- I am removing the index property from idle states as requested
- I will reword (again) min-residency-us
- I will use min-residency-us+exit-latency-us to sort the states
- I will repost the generic CPU idle code and streamlined bindings
  together to ease review
- I am NOT adding a substates property, since it is not needed at the
  moment (ie when using PSCI as entry method)
- We have to understand what to do with cache bindings (with power domain
  properties removed) since there is a series depending on them
  https://lkml.org/lkml/2014/4/4/436

Thoughts would be very appreciated at this point.

Thanks for your help,
Lorenzo

> ---
>  Documentation/devicetree/bindings/arm/cpus.txt     |  18 +
>  .../devicetree/bindings/arm/idle-states.txt        | 771 +++++++++++++++++++++
>  2 files changed, 789 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/idle-states.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
> index 9130435..79a1d9b 100644
> --- a/Documentation/devicetree/bindings/arm/cpus.txt
> +++ b/Documentation/devicetree/bindings/arm/cpus.txt
> @@ -191,6 +191,19 @@ nodes to be present and contain the properties described below.
>                           property identifying a 64-bit zero-initialised
>                           memory location.
> 
> +       - cpu-idle-states
> +               Usage: Optional
> +               Value type: <prop-encoded-array>
> +               Definition:
> +                       # List of phandles to idle state nodes supported
> +                         by this cpu [1].
> +
> +       - power-domain
> +               Usage: Optional
> +               Value type: <prop-encoded-array>
> +               Definition: A phandle and power domain specifier as defined by
> +                           bindings of power domain specified by [2].
> +
>  Example 1 (dual-cluster big.LITTLE system 32-bit):
> 
>         cpus {
> @@ -382,3 +395,8 @@ cpus {
>                 cpu-release-addr = <0 0x20000000>;
>         };
>  };
> +
> +[1] ARM Linux kernel documentation - idle states bindings
> +    Documentation/devicetree/bindings/arm/idle-states.txt
> +[2] Kernel documentation - power domain bindings
> +    Documentation/devicetree/bindings/power/power_domain.txt
> diff --git a/Documentation/devicetree/bindings/arm/idle-states.txt b/Documentation/devicetree/bindings/arm/idle-states.txt
> new file mode 100644
> index 0000000..fee176d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/idle-states.txt
> @@ -0,0 +1,771 @@
> +==========================================
> +ARM idle states binding description
> +==========================================
> +
> +==========================================
> +1 - Introduction
> +==========================================
> +
> +ARM systems contain HW capable of managing power consumption dynamically,
> +where cores can be put in different low-power states (ranging from simple
> +wfi to power gating) according to OSPM policies. The CPU states representing
> +the range of dynamic idle states that a processor can enter at run-time, can be
> +specified through device tree bindings representing the parameters required
> +to enter/exit specific idle states on a given processor.
> +
> +According to the Server Base System Architecture document (SBSA, [4]), the
> +power states an ARM CPU can be put into are identified by the following list:
> +
> +- Running
> +- Idle_standby
> +- Idle_retention
> +- Sleep
> +- Off
> +
> +The power states described in the SBSA document define the basic CPU states on
> +top of which ARM platforms implement power management schemes that allow an OS
> +PM implementation to put the processor in different idle states (which include
> +states listed above; "off" state is not an idle state since it does not have
> +wake-up capabilities, hence it is not considered in this document).
> +
> +Idle state parameters (eg entry latency) are platform specific and need to be
> +characterized with bindings that provide the required information to OSPM
> +code so that it can build the required tables and use them at runtime.
> +
> +The device tree binding definition for ARM idle states is the subject of this
> +document.
> +
> +===========================================
> +2 - idle-states node
> +===========================================
> +
> +ARM processor idle states are defined within the idle-states node, which is
> +a direct child of the cpus node and provides a container where the processor
> +idle states, defined as device tree nodes, are listed.
> +
> +- idle-states node
> +
> +       Usage: Optional - On ARM systems, is a container of processor idle
> +                         states nodes. If the system does not provide CPU
> +                         power management capabilities or the processor just
> +                         supports idle_standby an idle-states node is not
> +                         required.
> +
> +       Description: idle-states node is a container node, where its
> +                    subnodes describe the CPU idle states.
> +
> +       Node name must be "idle-states".
> +
> +       The idle-states node's parent node must be the cpus node.
> +
> +       The idle-states node's child nodes can be:
> +
> +       - one or more state nodes
> +
> +       Any other configuration is considered invalid.
> +
> +       An idle-states node defines the following properties:
> +
> +       - entry-method
> +               Usage: Required
> +               Value type: <stringlist>
> +               Definition: Describes the method by which a CPU enters the
> +                           idle states. This property is required and must be
> +                           one of:
> +
> +                           - "arm,psci"
> +                             ARM PSCI firmware interface [3].
> +
> +                           - "[vendor],[method]"
> +                             An implementation dependent string with
> +                             format "vendor,method", where vendor is a string
> +                             denoting the name of the manufacturer and
> +                             method is a string specifying the mechanism
> +                             used to enter the idle state.
> +
> +The nodes describing the idle states (state) can only be defined within the
> +idle-states node.
> +
> +Any other configuration is consider invalid and therefore must be ignored.
> +
> +===========================================
> +3 - state node
> +===========================================
> +
> +A state node represents an idle state description and must be defined as
> +follows:
> +
> +- state node
> +
> +       Description: must be child of either the idle-states node or
> +                    a state node.
> +
> +       The state node name shall follow standard device tree naming
> +       rules ([6], 2.2.1 "Node names"), in particular state nodes which
> +       are siblings within a single common parent must be given a unique name.
> +
> +       The idle state entered by executing the wfi instruction (idle_standby
> +       SBSA,[4][5]) is considered standard on all ARM platforms and therefore
> +       must not be listed.
> +
> +       A state node can contain state child nodes. A state node with
> +       children represents a hierarchical state, which is a superset of
> +       the child states.
> +
> +       A state node defines the following properties:
> +
> +       - compatible
> +               Usage: Required
> +               Value type: <stringlist>
> +               Definition: Must be "arm,idle-state".
> +
> +       - index
> +               Usage: Required
> +               Value type: <u32>
> +               Definition: It represents the idle state index.
> +                           The index must be given an increasing
> +                           value = {0, 1, ....}, starting from 0, with higher
> +                           values implying less power consumption.
> +                           Indices must be unique as seen from a cpu
> +                           perspective, ie phandles in the cpu nodes [1]
> +                           cpu-idle-states array property are not allowed to
> +                           point at idle state nodes having the same index
> +                           value.
> +
> +       - logic-state-retained
> +               Usage: See definition
> +               Value type: <none>
> +               Definition: if present logic is retained on state entry,
> +                           otherwise it is lost.
> +
> +       - cache-state-retained
> +               Usage: See definition
> +               Value type: <none>
> +               Definition: if present cache memory is retained on state entry,
> +                           otherwise it is lost.
> +
> +       - entry-method-param
> +               Usage: See definition.
> +               Value type: <u32>
> +               Definition: Depends on the idle-states node entry-method
> +                           property value. Refer to the entry-method bindings
> +                           for this property value definition.
> +
> +       - entry-latency-us
> +               Usage: Required
> +               Value type: <prop-encoded-array>
> +               Definition: u32 value representing worst case latency
> +                           in microseconds required to enter the idle state.
> +
> +       - exit-latency-us
> +               Usage: Required
> +               Value type: <prop-encoded-array>
> +               Definition: u32 value representing worst case latency
> +                           in microseconds required to exit the idle state.
> +
> +       - min-residency-us
> +               Usage: Required
> +               Value type: <prop-encoded-array>
> +               Definition: u32 value representing time in microseconds
> +                           required for the CPU to be in the idle state to
> +                           guarantee power savings maximization.
> +
> +       - power-domains
> +               Usage: Optional
> +               Value type: <prop-encoded-array>
> +               Definition: List of phandle and power domain specifiers ([2])
> +                           describing the power domains that are affected by
> +                           the idle state entry. All devices whose
> +                           power-domains property contains entries referring
> +                           to one of the power domains listed in this
> +                           property are affected by the idle state entry.
> +
> +===========================================
> +4 - Examples
> +===========================================
> +
> +Example 1 (ARM 64-bit, 16-cpu system):
> +
> +pd_clusters: power-domain-clusters at 80002000 {
> +       compatible = "arm,power-controller";
> +       reg = <0x0 0x80002000 0x0 0x1000>;
> +       #power-domain-cells = <1>;
> +       #address-cells = <2>;
> +       #size-cells = <2>;
> +
> +       pd_cores: power-domain-cores at 80000000 {
> +               compatible = "arm,power-controller";
> +               reg = <0x0 0x80000000 0x0 0x1000>;
> +               #power-domain-cells = <1>;
> +       };
> +};
> +
> +cpus {
> +       #size-cells = <0>;
> +       #address-cells = <2>;
> +
> +       idle-states {
> +               entry-method = "arm,psci-cpu-suspend";
> +
> +               CLUSTER_RETENTION_0: cluster-retention-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <2>;
> +                       logic-state-retained;
> +                       cache-state-retained;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <50>;
> +                       exit-latency-us = <100>;
> +                       min-residency-us = <250>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_RETENTION_0_0: cpu-retention-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               cache-state-retained;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <20>;
> +                               exit-latency-us = <40>;
> +                               min-residency-us = <30>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>,
> +                                               <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };
> +
> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <3>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <600>;
> +                       exit-latency-us = <1100>;
> +                       min-residency-us = <2700>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> +                               /* cpu sleep */
> +                               compatible = "arm,idle-state";
> +                               index = <1>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <250>;
> +                               exit-latency-us = <500>;
> +                               min-residency-us = <350>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>,
> +                                               <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };
> +               CLUSTER_RETENTION_1: cluster-retention-1 {
> +                       compatible = "arm,idle-state";
> +                       index = <2>;
> +                       logic-state-retained;
> +                       cache-state-retained;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <50>;
> +                       exit-latency-us = <100>;
> +                       min-residency-us = <270>;
> +                       power-domains = <&pd_clusters 1>;
> +                       CPU_RETENTION_1_0: cpu-retention-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               cache-state-retained;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <20>;
> +                               exit-latency-us = <40>;
> +                               min-residency-us = <30>;
> +                               power-domains = <&pd_cores 8>,
> +                                               <&pd_cores 9>,
> +                                               <&pd_cores 10>,
> +                                               <&pd_cores 11>,
> +                                               <&pd_cores 12>,
> +                                               <&pd_cores 13>,
> +                                               <&pd_cores 14>,
> +                                               <&pd_cores 15>;
> +                       };
> +               };
> +
> +               CLUSTER_SLEEP_1: cluster-sleep-1 {
> +                       compatible = "arm,idle-state";
> +                       index = <3>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <500>;
> +                       exit-latency-us = <1200>;
> +                       min-residency-us = <3500>;
> +                       power-domains = <&pd_clusters 1>;
> +                       CPU_SLEEP_1_0: cpu-sleep-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <1>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <70>;
> +                               exit-latency-us = <100>;
> +                               min-residency-us = <100>;
> +                               power-domains = <&pd_cores 8>,
> +                                               <&pd_cores 9>,
> +                                               <&pd_cores 10>,
> +                                               <&pd_cores 11>,
> +                                               <&pd_cores 12>,
> +                                               <&pd_cores 13>,
> +                                               <&pd_cores 14>,
> +                                               <&pd_cores 15>;
> +                       };
> +               };
> +       };
> +
> +       CPU0: cpu at 0 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x0>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_0>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_0: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 0>;
> +               };
> +               L2_0: l2-cache {
> +                       compatible = "arm,arch-cache";
> +                       power-domain = <&pd_clusters 0>;
> +               };
> +       };
> +
> +       CPU1: cpu at 1 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x1>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_1>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_1: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 1>;
> +               };
> +       };
> +
> +       CPU2: cpu at 100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x100>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_2>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_2: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 2>;
> +               };
> +       };
> +
> +       CPU3: cpu at 101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x101>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_3>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_3: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 3>;
> +               };
> +       };
> +
> +       CPU4: cpu at 10000 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x10000>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_4>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_4: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 4>;
> +               };
> +       };
> +
> +       CPU5: cpu at 10001 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x10001>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_5>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_5: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 5>;
> +               };
> +       };
> +
> +       CPU6: cpu at 10100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x10100>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_6>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_6: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 6>;
> +               };
> +       };
> +
> +       CPU7: cpu at 10101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a57";
> +               reg = <0x0 0x10101>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_7>;
> +               cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
> +                                  &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
> +               L1_7: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 7>;
> +               };
> +       };
> +
> +       CPU8: cpu at 100000000 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x0>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_8>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_8: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 8>;
> +               };
> +               L2_1: l2-cache {
> +                       compatible = "arm,arch-cache";
> +                       power-domain = <&pd_clusters 1>;
> +               };
> +       };
> +
> +       CPU9: cpu at 100000001 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x1>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_9>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_9: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 9>;
> +               };
> +       };
> +
> +       CPU10: cpu at 100000100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x100>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_10>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_10: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 10>;
> +               };
> +       };
> +
> +       CPU11: cpu at 100000101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x101>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_11>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_11: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 11>;
> +               };
> +       };
> +
> +       CPU12: cpu at 100010000 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x10000>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_12>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_12: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 12>;
> +               };
> +       };
> +
> +       CPU13: cpu at 100010001 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x10001>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_13>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_13: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 13>;
> +               };
> +       };
> +
> +       CPU14: cpu at 100010100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x10100>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_14>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_14: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 14>;
> +               };
> +       };
> +
> +       CPU15: cpu at 100010101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a53";
> +               reg = <0x1 0x10101>;
> +               enable-method = "psci";
> +               next-level-cache = <&L1_15>;
> +               cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
> +                                  &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
> +               L1_15: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 15>;
> +               };
> +       };
> +};
> +
> +Example 2 (ARM 32-bit, 8-cpu system, two clusters):
> +
> +pd_clusters: power-domain-clusters at 80002000 {
> +       compatible = "arm,power-controller";
> +       reg = <0x80002000 0x1000>;
> +       #power-domain-cells = <1>;
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       pd_cores: power-domain-cores at 80000000 {
> +               compatible = "arm,power-controller";
> +               reg = <0x80000000 0x1000>;
> +               #power-domain-cells = <1>;
> +       };
> +};
> +
> +cpus {
> +       #size-cells = <0>;
> +       #address-cells = <1>;
> +
> +       idle-states {
> +               entry-method = "arm,psci-cpu-suspend";
> +
> +               CLUSTER_SLEEP_0: cluster-sleep-0 {
> +                       compatible = "arm,idle-state";
> +                       index = <1>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <1000>;
> +                       exit-latency-us = <1500>;
> +                       min-residency-us = <1500>;
> +                       power-domains = <&pd_clusters 0>;
> +                       CPU_SLEEP_0_0: cpu-sleep-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <400>;
> +                               exit-latency-us = <500>;
> +                               min-residency-us = <300>;
> +                               power-domains = <&pd_cores 0>,
> +                                               <&pd_cores 1>,
> +                                               <&pd_cores 2>,
> +                                               <&pd_cores 3>;
> +                       };
> +               };
> +
> +               CLUSTER_SLEEP_1: cluster-sleep-1 {
> +                       compatible = "arm,idle-state";
> +                       index = <1>;
> +                       entry-method-param = <0x1010000>;
> +                       entry-latency-us = <800>;
> +                       exit-latency-us = <2000>;
> +                       min-residency-us = <6500>;
> +                       power-domains = <&pd_clusters 1>;
> +                       CPU_SLEEP_1_0: cpu-sleep-0 {
> +                               compatible = "arm,idle-state";
> +                               index = <0>;
> +                               entry-method-param = <0x0010000>;
> +                               entry-latency-us = <300>;
> +                               exit-latency-us = <500>;
> +                               min-residency-us = <500>;
> +                               power-domains = <&pd_cores 4>,
> +                                               <&pd_cores 5>,
> +                                               <&pd_cores 6>,
> +                                               <&pd_cores 7>;
> +                       };
> +               };
> +       };
> +
> +       CPU0: cpu at 0 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a15";
> +               reg = <0x0>;
> +               next-level-cache = <&L1_0>;
> +               cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
> +               L1_0: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 0>;
> +               };
> +               L2_0: l2-cache {
> +                       compatible = "arm,arch-cache";
> +                       power-domain = <&pd_clusters 0>;
> +               };
> +       };
> +
> +       CPU1: cpu at 1 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a15";
> +               reg = <0x1>;
> +               next-level-cache = <&L1_1>;
> +               cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
> +               L1_1: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 1>;
> +               };
> +       };
> +
> +       CPU2: cpu at 2 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a15";
> +               reg = <0x2>;
> +               next-level-cache = <&L1_2>;
> +               cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
> +               L1_2: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 2>;
> +               };
> +       };
> +
> +       CPU3: cpu at 3 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a15";
> +               reg = <0x3>;
> +               next-level-cache = <&L1_3>;
> +               cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
> +               L1_3: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_0>;
> +                       power-domain = <&pd_cores 3>;
> +               };
> +       };
> +
> +       CPU4: cpu at 100 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a7";
> +               reg = <0x100>;
> +               next-level-cache = <&L1_4>;
> +               cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
> +               L1_4: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 4>;
> +               };
> +               L2_1: l2-cache {
> +                       compatible = "arm,arch-cache";
> +                       power-domain = <&pd_clusters 1>;
> +               };
> +       };
> +
> +       CPU5: cpu at 101 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a7";
> +               reg = <0x101>;
> +               next-level-cache = <&L1_5>;
> +               cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
> +               L1_5: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 5>;
> +               };
> +       };
> +
> +       CPU6: cpu at 102 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a7";
> +               reg = <0x102>;
> +               next-level-cache = <&L1_6>;
> +               cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
> +               L1_6: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 6>;
> +               };
> +       };
> +
> +       CPU7: cpu at 103 {
> +               device_type = "cpu";
> +               compatible = "arm,cortex-a7";
> +               reg = <0x103>;
> +               next-level-cache = <&L1_7>;
> +               cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
> +               L1_7: l1-cache {
> +                       compatible = "arm,arch-cache";
> +                       next-level-cache = <&L2_1>;
> +                       power-domain = <&pd_cores 7>;
> +               };
> +       };
> +};
> +
> +===========================================
> +4 - References
> +===========================================
> +
> +[1] ARM Linux Kernel documentation - CPUs bindings
> +    Documentation/devicetree/bindings/arm/cpus.txt
> +
> +[2] ARM Linux Kernel documentation - power domain bindings
> +    Documentation/devicetree/bindings/power/power_domain.txt
> +
> +[3] ARM Linux Kernel documentation - PSCI bindings
> +    Documentation/devicetree/bindings/arm/psci.txt
> +
> +[4] ARM Server Base System Architecture (SBSA)
> +    http://infocenter.arm.com/help/index.jsp
> +
> +[5] ARM Architecture Reference Manuals
> +    http://infocenter.arm.com/help/index.jsp
> +
> +[6] ePAPR standard
> +    https://www.power.org/documentation/epapr-version-1-1/
> --
> 1.8.4
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2014-04-29 10:56 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-18 11:28 [PATCH RFC v5 0/3] ARM: defining idle states DT bindings Lorenzo Pieralisi
2014-03-18 11:28 ` Lorenzo Pieralisi
2014-03-18 11:28 ` [PATCH RFC v5 1/3] Documentation: devicetree: psci: define CPU suspend parameter Lorenzo Pieralisi
2014-03-18 11:28   ` Lorenzo Pieralisi
2014-03-18 11:28 ` [PATCH RFC v5 2/3] Documentation: arm: add cache DT bindings Lorenzo Pieralisi
2014-03-18 11:28   ` Lorenzo Pieralisi
2014-03-18 11:28 ` [PATCH RFC v5 3/3] Documentation: arm: define DT idle states bindings Lorenzo Pieralisi
2014-03-18 11:28   ` Lorenzo Pieralisi
2014-04-04 15:56   ` Lorenzo Pieralisi
2014-04-04 15:56     ` Lorenzo Pieralisi
2014-04-04 22:01     ` Sebastian Capella
2014-04-04 22:01       ` Sebastian Capella
2014-04-07 11:52       ` Lorenzo Pieralisi
2014-04-07 11:52         ` Lorenzo Pieralisi
2014-04-07 12:25     ` Vincent Guittot
2014-04-07 12:25       ` Vincent Guittot
2014-04-07 14:36       ` Lorenzo Pieralisi
2014-04-07 14:36         ` Lorenzo Pieralisi
2014-04-07 15:34         ` Vincent Guittot
2014-04-07 15:34           ` Vincent Guittot
2014-04-07 18:03           ` Lorenzo Pieralisi
2014-04-07 18:03             ` Lorenzo Pieralisi
2014-04-08  9:11             ` Vincent Guittot
2014-04-08  9:11               ` Vincent Guittot
2014-04-29 10:56   ` Lorenzo Pieralisi
2014-04-29 10:56     ` Lorenzo Pieralisi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.