All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] ARM: vf610: Suspend/resume support
@ 2014-09-22 17:09 ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

This patchset provides suspend/resume support for Freescale Vybrid
SoC (vf610). The code is generally aligned to the implementation
for i.MX6. The subsystems SRC and GPC need some changes to support
the Vybrid specific implementation.

This patchset relies on GPIO driver to be present (in order to
provide a wakeup source) as well as using the ARM Global Timer
clock source (the Vybrid specifc PIT clock source, vf_pit_timer.c
does not support shutdown).

The implemented sleep states (LP-RUN and STOP), are not the most
power saving functions available on Vybrid. Especially for
suspend-to-memory one of the LPSTOP modes looks more appropriate.
However, the complexity is somewhat higher (we would need to move
execution path to SRAM and store IOMUX and DDRMC configuration).
Currently, I have not the resources to look into that so I hope
that this initial code qualifies as power saving functions to be
applied.

Suspend-to-memory as well as standby mode is tested on Colibri
VF61.

Power measurement (Colibri VF61, whole module):
- Idle: 540mW
- LP-RUN: 220mW (standby)
- STOP: 200mW (mem)

Stefan Agner (9):
  ARM: dts: vf610: Add system reset controller (SRC)
  ARM: dts: vf610: add global power controller (GPC)
  ARM: dts: vf610: add on-chip SRAM
  ARM: dts: vf610-colibri: GPIO power key
  gpio: vf610: Extend with wakeup support
  ARM: imx: gpc: Support vf610 global power controller
  ARM: imx: src: Support vf610 system reset controller
  ARM: imx: clk-gate2: allow custom gate configuration
  ARM: vf610: initial suspend/resume support

 arch/arm/boot/dts/vf610-colibri-eval-v3.dts |  26 ++
 arch/arm/boot/dts/vf610.dtsi                |  33 +++
 arch/arm/mach-imx/Kconfig                   |   2 +
 arch/arm/mach-imx/Makefile                  |   1 +
 arch/arm/mach-imx/clk-gate2.c               |   7 +-
 arch/arm/mach-imx/clk-vf610.c               |   6 +
 arch/arm/mach-imx/clk.h                     |  13 +-
 arch/arm/mach-imx/common.h                  |  14 +-
 arch/arm/mach-imx/gpc.c                     |  61 ++--
 arch/arm/mach-imx/mach-imx6q.c              |   2 +-
 arch/arm/mach-imx/mach-imx6sl.c             |   2 +-
 arch/arm/mach-imx/mach-vf610.c              |   9 +
 arch/arm/mach-imx/pm-vf610.c                | 428 ++++++++++++++++++++++++++++
 arch/arm/mach-imx/src.c                     |  11 +
 drivers/gpio/gpio-vf610.c                   |  16 ++
 include/dt-bindings/clock/vf610-clock.h     |   3 +-
 16 files changed, 605 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm/mach-imx/pm-vf610.c

-- 
2.1.0


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

* [PATCH 0/9] ARM: vf610: Suspend/resume support
@ 2014-09-22 17:09 ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset provides suspend/resume support for Freescale Vybrid
SoC (vf610). The code is generally aligned to the implementation
for i.MX6. The subsystems SRC and GPC need some changes to support
the Vybrid specific implementation.

This patchset relies on GPIO driver to be present (in order to
provide a wakeup source) as well as using the ARM Global Timer
clock source (the Vybrid specifc PIT clock source, vf_pit_timer.c
does not support shutdown).

The implemented sleep states (LP-RUN and STOP), are not the most
power saving functions available on Vybrid. Especially for
suspend-to-memory one of the LPSTOP modes looks more appropriate.
However, the complexity is somewhat higher (we would need to move
execution path to SRAM and store IOMUX and DDRMC configuration).
Currently, I have not the resources to look into that so I hope
that this initial code qualifies as power saving functions to be
applied.

Suspend-to-memory as well as standby mode is tested on Colibri
VF61.

Power measurement (Colibri VF61, whole module):
- Idle: 540mW
- LP-RUN: 220mW (standby)
- STOP: 200mW (mem)

Stefan Agner (9):
  ARM: dts: vf610: Add system reset controller (SRC)
  ARM: dts: vf610: add global power controller (GPC)
  ARM: dts: vf610: add on-chip SRAM
  ARM: dts: vf610-colibri: GPIO power key
  gpio: vf610: Extend with wakeup support
  ARM: imx: gpc: Support vf610 global power controller
  ARM: imx: src: Support vf610 system reset controller
  ARM: imx: clk-gate2: allow custom gate configuration
  ARM: vf610: initial suspend/resume support

 arch/arm/boot/dts/vf610-colibri-eval-v3.dts |  26 ++
 arch/arm/boot/dts/vf610.dtsi                |  33 +++
 arch/arm/mach-imx/Kconfig                   |   2 +
 arch/arm/mach-imx/Makefile                  |   1 +
 arch/arm/mach-imx/clk-gate2.c               |   7 +-
 arch/arm/mach-imx/clk-vf610.c               |   6 +
 arch/arm/mach-imx/clk.h                     |  13 +-
 arch/arm/mach-imx/common.h                  |  14 +-
 arch/arm/mach-imx/gpc.c                     |  61 ++--
 arch/arm/mach-imx/mach-imx6q.c              |   2 +-
 arch/arm/mach-imx/mach-imx6sl.c             |   2 +-
 arch/arm/mach-imx/mach-vf610.c              |   9 +
 arch/arm/mach-imx/pm-vf610.c                | 428 ++++++++++++++++++++++++++++
 arch/arm/mach-imx/src.c                     |  11 +
 drivers/gpio/gpio-vf610.c                   |  16 ++
 include/dt-bindings/clock/vf610-clock.h     |   3 +-
 16 files changed, 605 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm/mach-imx/pm-vf610.c

-- 
2.1.0

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

* [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
  2014-09-22 17:09 ` Stefan Agner
  (?)
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, linux-kernel, stefan, linux-gpio, jingchang.lu, b20788,
	linux-arm-kernel

Add device tree property for system reset controller.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 3a6840c..122a64956 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -366,6 +366,13 @@
 				reg = <0x40034800 0x200>;
 				clocks = <&clks VF610_CLK_USBC0>;
 			};
+
+			src: src@4006e000 {
+				compatible = "fsl,vf610-src";
+				reg = <0x4006e000 0x1000>;
+				interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
+				#reset-cells = <0>;
+			};
 		};
 
 		aips1: aips-bus@40080000 {
-- 
2.1.0

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

* [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

Add device tree property for system reset controller.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 3a6840c..122a64956 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -366,6 +366,13 @@
 				reg = <0x40034800 0x200>;
 				clocks = <&clks VF610_CLK_USBC0>;
 			};
+
+			src: src@4006e000 {
+				compatible = "fsl,vf610-src";
+				reg = <0x4006e000 0x1000>;
+				interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
+				#reset-cells = <0>;
+			};
 		};
 
 		aips1: aips-bus@40080000 {
-- 
2.1.0


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

* [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

Add device tree property for system reset controller.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 3a6840c..122a64956 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -366,6 +366,13 @@
 				reg = <0x40034800 0x200>;
 				clocks = <&clks VF610_CLK_USBC0>;
 			};
+
+			src: src at 4006e000 {
+				compatible = "fsl,vf610-src";
+				reg = <0x4006e000 0x1000>;
+				interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
+				#reset-cells = <0>;
+			};
 		};
 
 		aips1: aips-bus at 40080000 {
-- 
2.1.0

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

* [PATCH 2/9] ARM: dts: vf610: add global power controller (GPC)
  2014-09-22 17:09 ` Stefan Agner
  (?)
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, linux-kernel, stefan, linux-gpio, jingchang.lu, b20788,
	linux-arm-kernel

Add global power controller module (GPC) to Vybrid device tree.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 122a64956..67bb3b7 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -367,6 +367,11 @@
 				clocks = <&clks VF610_CLK_USBC0>;
 			};
 
+			gpc: gpc@4006c000 {
+				compatible = "fsl,vf610-gpc";
+				reg = <0x4006c000 0x1000>;
+			};
+
 			src: src@4006e000 {
 				compatible = "fsl,vf610-src";
 				reg = <0x4006e000 0x1000>;
-- 
2.1.0

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

* [PATCH 2/9] ARM: dts: vf610: add global power controller (GPC)
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

Add global power controller module (GPC) to Vybrid device tree.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 122a64956..67bb3b7 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -367,6 +367,11 @@
 				clocks = <&clks VF610_CLK_USBC0>;
 			};
 
+			gpc: gpc@4006c000 {
+				compatible = "fsl,vf610-gpc";
+				reg = <0x4006c000 0x1000>;
+			};
+
 			src: src@4006e000 {
 				compatible = "fsl,vf610-src";
 				reg = <0x4006e000 0x1000>;
-- 
2.1.0


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

* [PATCH 2/9] ARM: dts: vf610: add global power controller (GPC)
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

Add global power controller module (GPC) to Vybrid device tree.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 122a64956..67bb3b7 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -367,6 +367,11 @@
 				clocks = <&clks VF610_CLK_USBC0>;
 			};
 
+			gpc: gpc at 4006c000 {
+				compatible = "fsl,vf610-gpc";
+				reg = <0x4006c000 0x1000>;
+			};
+
 			src: src at 4006e000 {
 				compatible = "fsl,vf610-src";
 				reg = <0x4006e000 0x1000>;
-- 
2.1.0

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

* [PATCH 3/9] ARM: dts: vf610: add on-chip SRAM
  2014-09-22 17:09 ` Stefan Agner
  (?)
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, linux-kernel, stefan, linux-gpio, jingchang.lu, b20788,
	linux-arm-kernel

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 67bb3b7..d2128e5 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -69,6 +69,27 @@
 		interrupt-parent = <&intc>;
 		ranges;
 
+		ocram0: sram@3f000000 {
+			compatible = "mmio-sram";
+			reg = <0x3f000000 0x40000>;
+		};
+
+		ocram1: sram@3f040000 {
+			compatible = "mmio-sram";
+			reg = <0x3f040000 0x40000>;
+		};
+
+		gfxram0: sram@3f400000 {
+			compatible = "mmio-sram";
+			reg = <0x3f400000 0x80000>;
+		};
+
+		/* used by L2 cache */
+		gfxram1: sram@3f480000 {
+			compatible = "mmio-sram";
+			reg = <0x3f480000 0x80000>;
+		};
+
 		aips0: aips-bus@40000000 {
 			compatible = "fsl,aips-bus", "simple-bus";
 			#address-cells = <1>;
-- 
2.1.0

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

* [PATCH 3/9] ARM: dts: vf610: add on-chip SRAM
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 67bb3b7..d2128e5 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -69,6 +69,27 @@
 		interrupt-parent = <&intc>;
 		ranges;
 
+		ocram0: sram@3f000000 {
+			compatible = "mmio-sram";
+			reg = <0x3f000000 0x40000>;
+		};
+
+		ocram1: sram@3f040000 {
+			compatible = "mmio-sram";
+			reg = <0x3f040000 0x40000>;
+		};
+
+		gfxram0: sram@3f400000 {
+			compatible = "mmio-sram";
+			reg = <0x3f400000 0x80000>;
+		};
+
+		/* used by L2 cache */
+		gfxram1: sram@3f480000 {
+			compatible = "mmio-sram";
+			reg = <0x3f480000 0x80000>;
+		};
+
 		aips0: aips-bus@40000000 {
 			compatible = "fsl,aips-bus", "simple-bus";
 			#address-cells = <1>;
-- 
2.1.0


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

* [PATCH 3/9] ARM: dts: vf610: add on-chip SRAM
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index 67bb3b7..d2128e5 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -69,6 +69,27 @@
 		interrupt-parent = <&intc>;
 		ranges;
 
+		ocram0: sram at 3f000000 {
+			compatible = "mmio-sram";
+			reg = <0x3f000000 0x40000>;
+		};
+
+		ocram1: sram at 3f040000 {
+			compatible = "mmio-sram";
+			reg = <0x3f040000 0x40000>;
+		};
+
+		gfxram0: sram at 3f400000 {
+			compatible = "mmio-sram";
+			reg = <0x3f400000 0x80000>;
+		};
+
+		/* used by L2 cache */
+		gfxram1: sram at 3f480000 {
+			compatible = "mmio-sram";
+			reg = <0x3f480000 0x80000>;
+		};
+
 		aips0: aips-bus at 40000000 {
 			compatible = "fsl,aips-bus", "simple-bus";
 			#address-cells = <1>;
-- 
2.1.0

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

* [PATCH 4/9] ARM: dts: vf610-colibri: GPIO power key
  2014-09-22 17:09 ` Stefan Agner
  (?)
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, linux-kernel, stefan, linux-gpio, jingchang.lu, b20788,
	linux-arm-kernel

Enable GPIO power key on pad 41 which is routed to our default
wakeup pin SO-DIMM 45.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610-colibri-eval-v3.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
index 7fb3066..e707243 100644
--- a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
@@ -8,6 +8,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/input/input.h>
 #include "vf610-colibri.dtsi"
 
 / {
@@ -17,6 +18,20 @@
 	chosen {
 		bootargs = "console=ttyLP0,115200";
 	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpiokeys>;
+
+		power {
+			label = "Power";
+			gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_POWER>;
+			debounce-interval = <10>;
+			gpio-key,wakeup;
+		};
+	};
 };
 
 &esdhc1 {
@@ -44,3 +59,14 @@
 &uart2 {
 	status = "okay";
 };
+
+
+&iomuxc {
+	vf610-colibri {
+		pinctrl_gpiokeys: gpiokeys {
+			fsl,pins = <
+				VF610_PAD_PTB19__GPIO_41	0x219d
+			>;
+		};
+	};
+};
-- 
2.1.0

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

* [PATCH 4/9] ARM: dts: vf610-colibri: GPIO power key
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

Enable GPIO power key on pad 41 which is routed to our default
wakeup pin SO-DIMM 45.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610-colibri-eval-v3.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
index 7fb3066..e707243 100644
--- a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
@@ -8,6 +8,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/input/input.h>
 #include "vf610-colibri.dtsi"
 
 / {
@@ -17,6 +18,20 @@
 	chosen {
 		bootargs = "console=ttyLP0,115200";
 	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpiokeys>;
+
+		power {
+			label = "Power";
+			gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_POWER>;
+			debounce-interval = <10>;
+			gpio-key,wakeup;
+		};
+	};
 };
 
 &esdhc1 {
@@ -44,3 +59,14 @@
 &uart2 {
 	status = "okay";
 };
+
+
+&iomuxc {
+	vf610-colibri {
+		pinctrl_gpiokeys: gpiokeys {
+			fsl,pins = <
+				VF610_PAD_PTB19__GPIO_41	0x219d
+			>;
+		};
+	};
+};
-- 
2.1.0


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

* [PATCH 4/9] ARM: dts: vf610-colibri: GPIO power key
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

Enable GPIO power key on pad 41 which is routed to our default
wakeup pin SO-DIMM 45.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/boot/dts/vf610-colibri-eval-v3.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
index 7fb3066..e707243 100644
--- a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts
@@ -8,6 +8,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/input/input.h>
 #include "vf610-colibri.dtsi"
 
 / {
@@ -17,6 +18,20 @@
 	chosen {
 		bootargs = "console=ttyLP0,115200";
 	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpiokeys>;
+
+		power {
+			label = "Power";
+			gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_POWER>;
+			debounce-interval = <10>;
+			gpio-key,wakeup;
+		};
+	};
 };
 
 &esdhc1 {
@@ -44,3 +59,14 @@
 &uart2 {
 	status = "okay";
 };
+
+
+&iomuxc {
+	vf610-colibri {
+		pinctrl_gpiokeys: gpiokeys {
+			fsl,pins = <
+				VF610_PAD_PTB19__GPIO_41	0x219d
+			>;
+		};
+	};
+};
-- 
2.1.0

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

* [PATCH 5/9] gpio: vf610: Extend with wakeup support
  2014-09-22 17:09 ` Stefan Agner
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

Support Vybrid GPIO's as wakeup source by requesting the parent
IRQ as wakeup IRQ.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
index 5f59424..50326af 100644
--- a/drivers/gpio/gpio-vf610.c
+++ b/drivers/gpio/gpio-vf610.c
@@ -196,12 +196,28 @@ static void vf610_gpio_irq_unmask(struct irq_data *d)
 			  pcr_base);
 }
 
+static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable)
+{
+	struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d);
+
+	if (enable)
+		enable_irq_wake(port->irq);
+	else
+		disable_irq_wake(port->irq);
+
+	return 0;
+}
+
+
 static struct irq_chip vf610_gpio_irq_chip = {
 	.name		= "gpio-vf610",
 	.irq_ack	= vf610_gpio_irq_ack,
 	.irq_mask	= vf610_gpio_irq_mask,
 	.irq_unmask	= vf610_gpio_irq_unmask,
 	.irq_set_type	= vf610_gpio_irq_set_type,
+#ifdef CONFIG_PM_SLEEP
+	.irq_set_wake	= vf610_gpio_irq_set_wake,
+#endif
 };
 
 static int vf610_gpio_probe(struct platform_device *pdev)
-- 
2.1.0

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

* [PATCH 5/9] gpio: vf610: Extend with wakeup support
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

Support Vybrid GPIO's as wakeup source by requesting the parent
IRQ as wakeup IRQ.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
index 5f59424..50326af 100644
--- a/drivers/gpio/gpio-vf610.c
+++ b/drivers/gpio/gpio-vf610.c
@@ -196,12 +196,28 @@ static void vf610_gpio_irq_unmask(struct irq_data *d)
 			  pcr_base);
 }
 
+static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable)
+{
+	struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d);
+
+	if (enable)
+		enable_irq_wake(port->irq);
+	else
+		disable_irq_wake(port->irq);
+
+	return 0;
+}
+
+
 static struct irq_chip vf610_gpio_irq_chip = {
 	.name		= "gpio-vf610",
 	.irq_ack	= vf610_gpio_irq_ack,
 	.irq_mask	= vf610_gpio_irq_mask,
 	.irq_unmask	= vf610_gpio_irq_unmask,
 	.irq_set_type	= vf610_gpio_irq_set_type,
+#ifdef CONFIG_PM_SLEEP
+	.irq_set_wake	= vf610_gpio_irq_set_wake,
+#endif
 };
 
 static int vf610_gpio_probe(struct platform_device *pdev)
-- 
2.1.0

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

* [PATCH 6/9] ARM: imx: gpc: Support vf610 global power controller
  2014-09-22 17:09 ` Stefan Agner
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

Support Vybrid SoC which has a similar global power controller
found in i.MX6 SoC's. The extension for the GIC interrupt
controller can be reused. However, Vybrid's GPC has no CPU
powerdown flag, hence we write this conditional.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/mach-imx/Kconfig       |  1 +
 arch/arm/mach-imx/common.h      |  3 +-
 arch/arm/mach-imx/gpc.c         | 61 +++++++++++++++++++++++++++--------------
 arch/arm/mach-imx/mach-imx6q.c  |  2 +-
 arch/arm/mach-imx/mach-imx6sl.c |  2 +-
 arch/arm/mach-imx/mach-vf610.c  |  7 +++++
 6 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index a566fbf3..70e6d56 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -633,6 +633,7 @@ config SOC_VF610
 	bool "Vybrid Family VF610 support"
 	select ARM_GIC
 	select PINCTRL_VF610
+	select HAVE_IMX_GPC
 	select ARM_GLOBAL_TIMER
 	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 	select PL310_ERRATA_769419 if CACHE_L2X0
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 1dabf43..4b753f5 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -103,7 +103,8 @@ static inline void imx_scu_map_io(void) {}
 static inline void imx_smp_prepare(void) {}
 #endif
 void imx_src_init(void);
-void imx_gpc_init(void);
+void imx6_gpc_init(void);
+void vf610_gpc_init(void);
 void imx_gpc_pre_suspend(bool arm_power_off);
 void imx_gpc_post_resume(void);
 void imx_gpc_mask_all(void);
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 82ea74e..4ac7a48 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -18,40 +18,42 @@
 #include <linux/irqchip/arm-gic.h>
 #include "common.h"
 
-#define GPC_IMR1		0x008
+#define IMX6_GPC_IMR1		0x008
+#define VF610_GPC_IMR1		0x044
 #define GPC_PGC_CPU_PDN		0x2a0
 
 #define IMR_NUM			4
 
 static void __iomem *gpc_base;
+static void __iomem *gpc_imr_base;
+static bool has_cpu_pdn;
 static u32 gpc_wake_irqs[IMR_NUM];
 static u32 gpc_saved_imrs[IMR_NUM];
 
 void imx_gpc_pre_suspend(bool arm_power_off)
 {
-	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
 	int i;
 
 	/* Tell GPC to power off ARM core when suspend */
-	if (arm_power_off)
+	if (arm_power_off && has_cpu_pdn)
 		writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
 
 	for (i = 0; i < IMR_NUM; i++) {
-		gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
-		writel_relaxed(~gpc_wake_irqs[i], reg_imr1 + i * 4);
+		gpc_saved_imrs[i] = readl_relaxed(gpc_imr_base + i * 4);
+		writel_relaxed(~gpc_wake_irqs[i], gpc_imr_base + i * 4);
 	}
 }
 
 void imx_gpc_post_resume(void)
 {
-	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
 	int i;
 
 	/* Keep ARM core powered on for other low-power modes */
-	writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN);
+	if (has_cpu_pdn)
+		writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN);
 
 	for (i = 0; i < IMR_NUM; i++)
-		writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
+		writel_relaxed(gpc_saved_imrs[i], gpc_imr_base + i * 4);
 }
 
 static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
@@ -72,23 +74,21 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
 
 void imx_gpc_mask_all(void)
 {
-	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
 	int i;
 
 	for (i = 0; i < IMR_NUM; i++) {
-		gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
-		writel_relaxed(~0, reg_imr1 + i * 4);
+		gpc_saved_imrs[i] = readl_relaxed(gpc_imr_base + i * 4);
+		writel_relaxed(~0, gpc_imr_base + i * 4);
 	}
 
 }
 
 void imx_gpc_restore_all(void)
 {
-	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
 	int i;
 
 	for (i = 0; i < IMR_NUM; i++)
-		writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
+		writel_relaxed(gpc_saved_imrs[i], gpc_imr_base + i * 4);
 }
 
 void imx_gpc_irq_unmask(struct irq_data *d)
@@ -100,7 +100,7 @@ void imx_gpc_irq_unmask(struct irq_data *d)
 	if (d->irq < 32)
 		return;
 
-	reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
+	reg = gpc_imr_base + (d->irq / 32 - 1) * 4;
 	val = readl_relaxed(reg);
 	val &= ~(1 << d->irq % 32);
 	writel_relaxed(val, reg);
@@ -115,27 +115,48 @@ void imx_gpc_irq_mask(struct irq_data *d)
 	if (d->irq < 32)
 		return;
 
-	reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
+	reg = gpc_imr_base + (d->irq / 32 - 1) * 4;
 	val = readl_relaxed(reg);
 	val |= 1 << (d->irq % 32);
 	writel_relaxed(val, reg);
 }
 
-void __init imx_gpc_init(void)
+static void __init imx_gpc_init(void)
 {
-	struct device_node *np;
 	int i;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
-	gpc_base = of_iomap(np, 0);
 	WARN_ON(!gpc_base);
 
 	/* Initially mask all interrupts */
 	for (i = 0; i < IMR_NUM; i++)
-		writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
+		writel_relaxed(~0, gpc_imr_base + i * 4);
 
 	/* Register GPC as the secondary interrupt controller behind GIC */
 	gic_arch_extn.irq_mask = imx_gpc_irq_mask;
 	gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
 	gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
 }
+
+void __init imx6_gpc_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
+	gpc_base = of_iomap(np, 0);
+	gpc_imr_base = gpc_base + IMX6_GPC_IMR1;
+	has_cpu_pdn = true;
+
+	imx_gpc_init();
+}
+
+void __init vf610_gpc_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,vf610-gpc");
+	gpc_base = of_iomap(np, 0);
+	gpc_imr_base = gpc_base + VF610_GPC_IMR1;
+	has_cpu_pdn = false;
+
+	imx_gpc_init();
+}
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index d51c6e9..b26dc73 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -392,7 +392,7 @@ static void __init imx6q_init_irq(void)
 	imx_init_revision_from_anatop();
 	imx_init_l2cache();
 	imx_src_init();
-	imx_gpc_init();
+	imx6_gpc_init();
 	irqchip_init();
 }
 
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index ed263a2..df462d6 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -66,7 +66,7 @@ static void __init imx6sl_init_irq(void)
 	imx_init_revision_from_anatop();
 	imx_init_l2cache();
 	imx_src_init();
-	imx_gpc_init();
+	imx6_gpc_init();
 	irqchip_init();
 }
 
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index ee7e57b..532f18f 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -14,6 +14,12 @@
 
 #include "common.h"
 
+static void __init vf610_init_irq(void)
+{
+	vf610_gpc_init();
+	irqchip_init();
+}
+
 static void __init vf610_init_machine(void)
 {
 	mxc_arch_reset_init_dt();
@@ -29,6 +35,7 @@ DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)")
 	.l2c_aux_val	= 0,
 	.l2c_aux_mask	= ~0,
 	.init_machine   = vf610_init_machine,
+	.init_irq	= vf610_init_irq,
 	.dt_compat	= vf610_dt_compat,
 	.restart	= mxc_restart,
 MACHINE_END
-- 
2.1.0


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

* [PATCH 6/9] ARM: imx: gpc: Support vf610 global power controller
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

Support Vybrid SoC which has a similar global power controller
found in i.MX6 SoC's. The extension for the GIC interrupt
controller can be reused. However, Vybrid's GPC has no CPU
powerdown flag, hence we write this conditional.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/mach-imx/Kconfig       |  1 +
 arch/arm/mach-imx/common.h      |  3 +-
 arch/arm/mach-imx/gpc.c         | 61 +++++++++++++++++++++++++++--------------
 arch/arm/mach-imx/mach-imx6q.c  |  2 +-
 arch/arm/mach-imx/mach-imx6sl.c |  2 +-
 arch/arm/mach-imx/mach-vf610.c  |  7 +++++
 6 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index a566fbf3..70e6d56 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -633,6 +633,7 @@ config SOC_VF610
 	bool "Vybrid Family VF610 support"
 	select ARM_GIC
 	select PINCTRL_VF610
+	select HAVE_IMX_GPC
 	select ARM_GLOBAL_TIMER
 	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 	select PL310_ERRATA_769419 if CACHE_L2X0
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 1dabf43..4b753f5 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -103,7 +103,8 @@ static inline void imx_scu_map_io(void) {}
 static inline void imx_smp_prepare(void) {}
 #endif
 void imx_src_init(void);
-void imx_gpc_init(void);
+void imx6_gpc_init(void);
+void vf610_gpc_init(void);
 void imx_gpc_pre_suspend(bool arm_power_off);
 void imx_gpc_post_resume(void);
 void imx_gpc_mask_all(void);
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 82ea74e..4ac7a48 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -18,40 +18,42 @@
 #include <linux/irqchip/arm-gic.h>
 #include "common.h"
 
-#define GPC_IMR1		0x008
+#define IMX6_GPC_IMR1		0x008
+#define VF610_GPC_IMR1		0x044
 #define GPC_PGC_CPU_PDN		0x2a0
 
 #define IMR_NUM			4
 
 static void __iomem *gpc_base;
+static void __iomem *gpc_imr_base;
+static bool has_cpu_pdn;
 static u32 gpc_wake_irqs[IMR_NUM];
 static u32 gpc_saved_imrs[IMR_NUM];
 
 void imx_gpc_pre_suspend(bool arm_power_off)
 {
-	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
 	int i;
 
 	/* Tell GPC to power off ARM core when suspend */
-	if (arm_power_off)
+	if (arm_power_off && has_cpu_pdn)
 		writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
 
 	for (i = 0; i < IMR_NUM; i++) {
-		gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
-		writel_relaxed(~gpc_wake_irqs[i], reg_imr1 + i * 4);
+		gpc_saved_imrs[i] = readl_relaxed(gpc_imr_base + i * 4);
+		writel_relaxed(~gpc_wake_irqs[i], gpc_imr_base + i * 4);
 	}
 }
 
 void imx_gpc_post_resume(void)
 {
-	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
 	int i;
 
 	/* Keep ARM core powered on for other low-power modes */
-	writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN);
+	if (has_cpu_pdn)
+		writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN);
 
 	for (i = 0; i < IMR_NUM; i++)
-		writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
+		writel_relaxed(gpc_saved_imrs[i], gpc_imr_base + i * 4);
 }
 
 static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
@@ -72,23 +74,21 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on)
 
 void imx_gpc_mask_all(void)
 {
-	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
 	int i;
 
 	for (i = 0; i < IMR_NUM; i++) {
-		gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
-		writel_relaxed(~0, reg_imr1 + i * 4);
+		gpc_saved_imrs[i] = readl_relaxed(gpc_imr_base + i * 4);
+		writel_relaxed(~0, gpc_imr_base + i * 4);
 	}
 
 }
 
 void imx_gpc_restore_all(void)
 {
-	void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
 	int i;
 
 	for (i = 0; i < IMR_NUM; i++)
-		writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4);
+		writel_relaxed(gpc_saved_imrs[i], gpc_imr_base + i * 4);
 }
 
 void imx_gpc_irq_unmask(struct irq_data *d)
@@ -100,7 +100,7 @@ void imx_gpc_irq_unmask(struct irq_data *d)
 	if (d->irq < 32)
 		return;
 
-	reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
+	reg = gpc_imr_base + (d->irq / 32 - 1) * 4;
 	val = readl_relaxed(reg);
 	val &= ~(1 << d->irq % 32);
 	writel_relaxed(val, reg);
@@ -115,27 +115,48 @@ void imx_gpc_irq_mask(struct irq_data *d)
 	if (d->irq < 32)
 		return;
 
-	reg = gpc_base + GPC_IMR1 + (d->irq / 32 - 1) * 4;
+	reg = gpc_imr_base + (d->irq / 32 - 1) * 4;
 	val = readl_relaxed(reg);
 	val |= 1 << (d->irq % 32);
 	writel_relaxed(val, reg);
 }
 
-void __init imx_gpc_init(void)
+static void __init imx_gpc_init(void)
 {
-	struct device_node *np;
 	int i;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
-	gpc_base = of_iomap(np, 0);
 	WARN_ON(!gpc_base);
 
 	/* Initially mask all interrupts */
 	for (i = 0; i < IMR_NUM; i++)
-		writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
+		writel_relaxed(~0, gpc_imr_base + i * 4);
 
 	/* Register GPC as the secondary interrupt controller behind GIC */
 	gic_arch_extn.irq_mask = imx_gpc_irq_mask;
 	gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
 	gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
 }
+
+void __init imx6_gpc_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
+	gpc_base = of_iomap(np, 0);
+	gpc_imr_base = gpc_base + IMX6_GPC_IMR1;
+	has_cpu_pdn = true;
+
+	imx_gpc_init();
+}
+
+void __init vf610_gpc_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,vf610-gpc");
+	gpc_base = of_iomap(np, 0);
+	gpc_imr_base = gpc_base + VF610_GPC_IMR1;
+	has_cpu_pdn = false;
+
+	imx_gpc_init();
+}
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index d51c6e9..b26dc73 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -392,7 +392,7 @@ static void __init imx6q_init_irq(void)
 	imx_init_revision_from_anatop();
 	imx_init_l2cache();
 	imx_src_init();
-	imx_gpc_init();
+	imx6_gpc_init();
 	irqchip_init();
 }
 
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index ed263a2..df462d6 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -66,7 +66,7 @@ static void __init imx6sl_init_irq(void)
 	imx_init_revision_from_anatop();
 	imx_init_l2cache();
 	imx_src_init();
-	imx_gpc_init();
+	imx6_gpc_init();
 	irqchip_init();
 }
 
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index ee7e57b..532f18f 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -14,6 +14,12 @@
 
 #include "common.h"
 
+static void __init vf610_init_irq(void)
+{
+	vf610_gpc_init();
+	irqchip_init();
+}
+
 static void __init vf610_init_machine(void)
 {
 	mxc_arch_reset_init_dt();
@@ -29,6 +35,7 @@ DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)")
 	.l2c_aux_val	= 0,
 	.l2c_aux_mask	= ~0,
 	.init_machine   = vf610_init_machine,
+	.init_irq	= vf610_init_irq,
 	.dt_compat	= vf610_dt_compat,
 	.restart	= mxc_restart,
 MACHINE_END
-- 
2.1.0

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

* [PATCH 7/9] ARM: imx: src: Support vf610 system reset controller
  2014-09-22 17:09 ` Stefan Agner
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

Support Vybrid SoC's system reset controller (SRC). Currently we
don't register a reset controller but only support the imx_cpu_jump
and imx_cpu_arg functions.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/mach-imx/Kconfig      |  1 +
 arch/arm/mach-imx/common.h     |  1 +
 arch/arm/mach-imx/mach-vf610.c |  1 +
 arch/arm/mach-imx/src.c        | 11 +++++++++++
 4 files changed, 14 insertions(+)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 70e6d56..f393775 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -634,6 +634,7 @@ config SOC_VF610
 	select ARM_GIC
 	select PINCTRL_VF610
 	select HAVE_IMX_GPC
+	select HAVE_IMX_SRC
 	select ARM_GLOBAL_TIMER
 	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 	select PL310_ERRATA_769419 if CACHE_L2X0
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 4b753f5..ca7a0d9 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -103,6 +103,7 @@ static inline void imx_scu_map_io(void) {}
 static inline void imx_smp_prepare(void) {}
 #endif
 void imx_src_init(void);
+void vf610_src_init(void);
 void imx6_gpc_init(void);
 void vf610_gpc_init(void);
 void imx_gpc_pre_suspend(bool arm_power_off);
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index 532f18f..eef3496 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -16,6 +16,7 @@
 
 static void __init vf610_init_irq(void)
 {
+	vf610_src_init();
 	vf610_gpc_init();
 	irqchip_init();
 }
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index 45f7f4e..a1f5160 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -140,3 +140,14 @@ void __init imx_src_init(void)
 	writel_relaxed(val, src_base + SRC_SCR);
 	spin_unlock(&scr_lock);
 }
+
+void __init vf610_src_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,vf610-src");
+	if (!np)
+		return;
+	src_base = of_iomap(np, 0);
+	WARN_ON(!src_base);
+}
-- 
2.1.0

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

* [PATCH 7/9] ARM: imx: src: Support vf610 system reset controller
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

Support Vybrid SoC's system reset controller (SRC). Currently we
don't register a reset controller but only support the imx_cpu_jump
and imx_cpu_arg functions.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/mach-imx/Kconfig      |  1 +
 arch/arm/mach-imx/common.h     |  1 +
 arch/arm/mach-imx/mach-vf610.c |  1 +
 arch/arm/mach-imx/src.c        | 11 +++++++++++
 4 files changed, 14 insertions(+)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 70e6d56..f393775 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -634,6 +634,7 @@ config SOC_VF610
 	select ARM_GIC
 	select PINCTRL_VF610
 	select HAVE_IMX_GPC
+	select HAVE_IMX_SRC
 	select ARM_GLOBAL_TIMER
 	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 	select PL310_ERRATA_769419 if CACHE_L2X0
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 4b753f5..ca7a0d9 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -103,6 +103,7 @@ static inline void imx_scu_map_io(void) {}
 static inline void imx_smp_prepare(void) {}
 #endif
 void imx_src_init(void);
+void vf610_src_init(void);
 void imx6_gpc_init(void);
 void vf610_gpc_init(void);
 void imx_gpc_pre_suspend(bool arm_power_off);
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index 532f18f..eef3496 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -16,6 +16,7 @@
 
 static void __init vf610_init_irq(void)
 {
+	vf610_src_init();
 	vf610_gpc_init();
 	irqchip_init();
 }
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index 45f7f4e..a1f5160 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -140,3 +140,14 @@ void __init imx_src_init(void)
 	writel_relaxed(val, src_base + SRC_SCR);
 	spin_unlock(&scr_lock);
 }
+
+void __init vf610_src_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,vf610-src");
+	if (!np)
+		return;
+	src_base = of_iomap(np, 0);
+	WARN_ON(!src_base);
+}
-- 
2.1.0

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

* [PATCH 8/9] ARM: imx: clk-gate2: allow custom gate configuration
  2014-09-22 17:09 ` Stefan Agner
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

The 2-bit gates found i.MX and Vybrid SoC support different clock
configuration:

0b00: clk disabled
0b01: clk enabled in RUN mode but disabled in WAIT and STOP mode
0b10: clk enabled in RUN, WAIT and STOP mode (only Vybrid)
0b11: clk enabled in RUN and WAIT mode

For some clocks, we might want to configure different behaviour,
e.g. a memory clock should be on even in STOP mode. Add a new
function imx_clk_gate2_cgr which allow to configure specific
gate values through the cgr_val parameter.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/mach-imx/clk-gate2.c           |  7 +++++--
 arch/arm/mach-imx/clk-vf610.c           |  3 +++
 arch/arm/mach-imx/clk.h                 | 13 ++++++++++---
 include/dt-bindings/clock/vf610-clock.h |  3 ++-
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
index 84acdfd..8c22a84 100644
--- a/arch/arm/mach-imx/clk-gate2.c
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -31,6 +31,7 @@ struct clk_gate2 {
 	struct clk_hw hw;
 	void __iomem	*reg;
 	u8		bit_idx;
+	u8		cgr_val;
 	u8		flags;
 	spinlock_t	*lock;
 	unsigned int	*share_count;
@@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw)
 		goto out;
 
 	reg = readl(gate->reg);
-	reg |= 3 << gate->bit_idx;
+	reg &= ~(3 << gate->bit_idx);
+	reg |= gate->cgr_val << gate->bit_idx;
 	writel(reg, gate->reg);
 
 out:
@@ -110,7 +112,7 @@ static struct clk_ops clk_gate2_ops = {
 
 struct clk *clk_register_gate2(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
-		void __iomem *reg, u8 bit_idx,
+		void __iomem *reg, u8 bit_idx, u8 cgr_val,
 		u8 clk_gate2_flags, spinlock_t *lock,
 		unsigned int *share_count)
 {
@@ -125,6 +127,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
 	/* struct clk_gate2 assignments */
 	gate->reg = reg;
 	gate->bit_idx = bit_idx;
+	gate->cgr_val = cgr_val;
 	gate->flags = clk_gate2_flags;
 	gate->lock = lock;
 
diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
index a178184..1034e78 100644
--- a/arch/arm/mach-imx/clk-vf610.c
+++ b/arch/arm/mach-imx/clk-vf610.c
@@ -103,6 +103,7 @@ static struct clk_onecell_data clk_data;
 static unsigned int const clks_init_on[] __initconst = {
 	VF610_CLK_SYS_BUS,
 	VF610_CLK_DDR_SEL,
+	VF610_CLK_DDRMC,
 };
 
 static void __init vf610_clocks_init(struct device_node *ccm_node)
@@ -171,6 +172,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_main_div", "pll4_main", 0, CCM_CACRR, 6, 3, 0, pll4_main_div_table, &imx_ccm_lock);
 	clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_main_div", "pll6_main", CCM_CACRR, 21, 1);
 
+	clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
+
 	clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_main", PLL3_CTRL, 6);
 	clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_main", PLL7_CTRL, 6);
 
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 4cdf8b6..d22e339 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -29,7 +29,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 
 struct clk *clk_register_gate2(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
-		void __iomem *reg, u8 bit_idx,
+		void __iomem *reg, u8 bit_idx, u8 cgr_val,
 		u8 clk_gate_flags, spinlock_t *lock,
 		unsigned int *share_count);
 
@@ -43,7 +43,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
 		void __iomem *reg, u8 shift)
 {
 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
-			shift, 0, &imx_ccm_lock, NULL);
+			shift, 0x3, 0, &imx_ccm_lock, NULL);
 }
 
 static inline struct clk *imx_clk_gate2_shared(const char *name,
@@ -51,7 +51,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
 		unsigned int *share_count)
 {
 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
-			shift, 0, &imx_ccm_lock, share_count);
+			shift, 0x3, 0, &imx_ccm_lock, share_count);
+}
+
+static inline struct clk *imx_clk_gate2_cgr(const char *name,
+		const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
+{
+	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+			shift, cgr_val, 0, &imx_ccm_lock, NULL);
 }
 
 struct clk *imx_clk_pfd(const char *name, const char *parent_name,
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index d6b56b2..84c4809 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -169,6 +169,7 @@
 #define VF610_CLK_PLL7_MAIN		156
 #define VF610_CLK_USBPHY0		157
 #define VF610_CLK_USBPHY1		158
-#define VF610_CLK_END			159
+#define VF610_CLK_DDRMC			159
+#define VF610_CLK_END			160
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
-- 
2.1.0

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

* [PATCH 8/9] ARM: imx: clk-gate2: allow custom gate configuration
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

The 2-bit gates found i.MX and Vybrid SoC support different clock
configuration:

0b00: clk disabled
0b01: clk enabled in RUN mode but disabled in WAIT and STOP mode
0b10: clk enabled in RUN, WAIT and STOP mode (only Vybrid)
0b11: clk enabled in RUN and WAIT mode

For some clocks, we might want to configure different behaviour,
e.g. a memory clock should be on even in STOP mode. Add a new
function imx_clk_gate2_cgr which allow to configure specific
gate values through the cgr_val parameter.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/mach-imx/clk-gate2.c           |  7 +++++--
 arch/arm/mach-imx/clk-vf610.c           |  3 +++
 arch/arm/mach-imx/clk.h                 | 13 ++++++++++---
 include/dt-bindings/clock/vf610-clock.h |  3 ++-
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
index 84acdfd..8c22a84 100644
--- a/arch/arm/mach-imx/clk-gate2.c
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -31,6 +31,7 @@ struct clk_gate2 {
 	struct clk_hw hw;
 	void __iomem	*reg;
 	u8		bit_idx;
+	u8		cgr_val;
 	u8		flags;
 	spinlock_t	*lock;
 	unsigned int	*share_count;
@@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw)
 		goto out;
 
 	reg = readl(gate->reg);
-	reg |= 3 << gate->bit_idx;
+	reg &= ~(3 << gate->bit_idx);
+	reg |= gate->cgr_val << gate->bit_idx;
 	writel(reg, gate->reg);
 
 out:
@@ -110,7 +112,7 @@ static struct clk_ops clk_gate2_ops = {
 
 struct clk *clk_register_gate2(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
-		void __iomem *reg, u8 bit_idx,
+		void __iomem *reg, u8 bit_idx, u8 cgr_val,
 		u8 clk_gate2_flags, spinlock_t *lock,
 		unsigned int *share_count)
 {
@@ -125,6 +127,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
 	/* struct clk_gate2 assignments */
 	gate->reg = reg;
 	gate->bit_idx = bit_idx;
+	gate->cgr_val = cgr_val;
 	gate->flags = clk_gate2_flags;
 	gate->lock = lock;
 
diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
index a178184..1034e78 100644
--- a/arch/arm/mach-imx/clk-vf610.c
+++ b/arch/arm/mach-imx/clk-vf610.c
@@ -103,6 +103,7 @@ static struct clk_onecell_data clk_data;
 static unsigned int const clks_init_on[] __initconst = {
 	VF610_CLK_SYS_BUS,
 	VF610_CLK_DDR_SEL,
+	VF610_CLK_DDRMC,
 };
 
 static void __init vf610_clocks_init(struct device_node *ccm_node)
@@ -171,6 +172,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_main_div", "pll4_main", 0, CCM_CACRR, 6, 3, 0, pll4_main_div_table, &imx_ccm_lock);
 	clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_main_div", "pll6_main", CCM_CACRR, 21, 1);
 
+	clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
+
 	clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_main", PLL3_CTRL, 6);
 	clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_main", PLL7_CTRL, 6);
 
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 4cdf8b6..d22e339 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -29,7 +29,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 
 struct clk *clk_register_gate2(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
-		void __iomem *reg, u8 bit_idx,
+		void __iomem *reg, u8 bit_idx, u8 cgr_val,
 		u8 clk_gate_flags, spinlock_t *lock,
 		unsigned int *share_count);
 
@@ -43,7 +43,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
 		void __iomem *reg, u8 shift)
 {
 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
-			shift, 0, &imx_ccm_lock, NULL);
+			shift, 0x3, 0, &imx_ccm_lock, NULL);
 }
 
 static inline struct clk *imx_clk_gate2_shared(const char *name,
@@ -51,7 +51,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
 		unsigned int *share_count)
 {
 	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
-			shift, 0, &imx_ccm_lock, share_count);
+			shift, 0x3, 0, &imx_ccm_lock, share_count);
+}
+
+static inline struct clk *imx_clk_gate2_cgr(const char *name,
+		const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
+{
+	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+			shift, cgr_val, 0, &imx_ccm_lock, NULL);
 }
 
 struct clk *imx_clk_pfd(const char *name, const char *parent_name,
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index d6b56b2..84c4809 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -169,6 +169,7 @@
 #define VF610_CLK_PLL7_MAIN		156
 #define VF610_CLK_USBPHY0		157
 #define VF610_CLK_USBPHY1		158
-#define VF610_CLK_END			159
+#define VF610_CLK_DDRMC			159
+#define VF610_CLK_END			160
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
-- 
2.1.0

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

* [PATCH 9/9] ARM: vf610: initial suspend/resume support
  2014-09-22 17:09 ` Stefan Agner
@ 2014-09-22 17:09   ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: shawn.guo, kernel, linus.walleij, gnurou
  Cc: linux, jingchang.lu, b20788, linux-arm-kernel, linux-kernel,
	linux-gpio, stefan

This patch adds initial suspend/resume support for Vybrid SoC.
The standby sleep state puts the module in LP-RUN mode which
allows to the SoC to be woken by a regular interrupt. The mem
sleep state (Suspend-to-RAM) uses the STOP mode which puts the
memory in self-refresh mode but keeps the memory clock enabled.
To wake the SoC a power management wakeup IRQ need to be enabled
using irq_set_irq_wake (e.g. through a GPIO).

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/mach-imx/Makefile     |   1 +
 arch/arm/mach-imx/clk-vf610.c  |   3 +
 arch/arm/mach-imx/common.h     |  10 +
 arch/arm/mach-imx/mach-vf610.c |   1 +
 arch/arm/mach-imx/pm-vf610.c   | 428 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 443 insertions(+)
 create mode 100644 arch/arm/mach-imx/pm-vf610.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 6e4fcd8..0f558aa 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -103,6 +103,7 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
 endif
 obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
+obj-$(CONFIG_SOC_VF610) += pm-vf610.o
 
 obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
 obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
index 1034e78..fbaa708 100644
--- a/arch/arm/mach-imx/clk-vf610.c
+++ b/arch/arm/mach-imx/clk-vf610.c
@@ -13,6 +13,7 @@
 #include <dt-bindings/clock/vf610-clock.h>
 
 #include "clk.h"
+#include "common.h"
 
 #define CCM_CCR			(ccm_base + 0x00)
 #define CCM_CSR			(ccm_base + 0x04)
@@ -131,6 +132,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 	ccm_base = of_iomap(np, 0);
 	BUG_ON(!ccm_base);
 
+	vf610_pm_set_ccm_base(ccm_base);
+
 	clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels));
 	clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels));
 
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index ca7a0d9..6dd360f 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -80,6 +80,13 @@ enum mxc_cpu_pwr_mode {
 	STOP_POWER_OFF,		/* STOP + SRPG */
 };
 
+enum vf610_cpu_pwr_mode {
+	VF610_RUN,
+	VF610_LP_RUN,
+	VF610_STOP,
+	VF610_LP_STOP,
+};
+
 enum mx3_cpu_pwr_mode {
 	MX3_RUN,
 	MX3_WAIT,
@@ -125,6 +132,7 @@ int imx_cpu_kill(unsigned int cpu);
 #ifdef CONFIG_SUSPEND
 void v7_cpu_resume(void);
 void imx6_suspend(void __iomem *ocram_vbase);
+void vf610_suspend(void);
 #else
 static inline void v7_cpu_resume(void) {}
 static inline void imx6_suspend(void __iomem *ocram_vbase) {}
@@ -135,6 +143,8 @@ void imx6dl_pm_init(void);
 void imx6sl_pm_init(void);
 void imx6sx_pm_init(void);
 void imx6q_pm_set_ccm_base(void __iomem *base);
+void vf610_pm_init(void);
+void vf610_pm_set_ccm_base(void __iomem *base);
 
 #ifdef CONFIG_PM
 void imx51_pm_init(void);
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index eef3496..79f0461 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -25,6 +25,7 @@ static void __init vf610_init_machine(void)
 {
 	mxc_arch_reset_init_dt();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+	vf610_pm_init();
 }
 
 static const char * const vf610_dt_compat[] __initconst = {
diff --git a/arch/arm/mach-imx/pm-vf610.c b/arch/arm/mach-imx/pm-vf610.c
new file mode 100644
index 0000000..87dbbac
--- /dev/null
+++ b/arch/arm/mach-imx/pm-vf610.c
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2014 Toradex AG
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/genalloc.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <linux/clk.h>
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include "common.h"
+
+#define CCR				0x0
+#define BM_CCR_FIRC_EN			(0x1 << 16)
+#define BM_CCR_FXOSC_EN			(0x1 << 12)
+
+#define CCSR				0x8
+#define BM_CCSR_DDRC_CLK_SEL		(0x1 << 6)
+#define BM_CCSR_FAST_CLK_SEL		(0x1 << 5)
+#define BM_CCSR_SLOW_CLK_SEL		(0x1 << 4)
+#define BM_CCSR_SYS_CLK_SEL_MASK	(0x7 << 0)
+
+#define CLPCR				0x2c
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM	(0x1 << 5)
+#define BM_CLPCR_SBYOS			(0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC		(0x1 << 7)
+#define BM_CLPCR_ANADIG_STOP_MODE	(0x1 << 8)
+#define BM_CLPCR_FXOSC_BYPSEN		(0x1 << 10)
+#define BM_CLPCR_FXOSC_PWRDWN		(0x1 << 11)
+#define BM_CLPCR_MASK_CORE0_WFI		(0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI		(0x1 << 23)
+#define BM_CLPCR_MASK_SCU_IDLE		(0x1 << 24)
+#define BM_CLPCR_MASK_L2CC_IDLE		(0x1 << 25)
+
+#define CGPR				0x64
+#define BM_CGPR_INT_MEM_CLK_LPM		(0x1 << 17)
+
+#define GPC_PGCR			0x0
+#define BM_PGCR_DS_STOP			(0x1 << 7)
+#define BM_PGCR_DS_LPSTOP		(0x1 << 6)
+#define BM_PGCR_WB_STOP			(0x1 << 4)
+#define BM_PGCR_HP_OFF			(0x1 << 3)
+
+#define GPC_LPMR			0x40
+#define BM_LPMR_RUN			0x0
+#define BM_LPMR_STOP			0x2
+
+#define ANATOP_PLL1_CTRL		0x270
+#define ANATOP_PLL2_CTRL		0x30
+#define ANATOP_PLL3_CTRL		0x10
+#define ANATOP_PLL4_CTRL		0x70
+#define ANATOP_PLL5_CTRL		0xe0
+#define ANATOP_PLL6_CTRL		0xa0
+#define ANATOP_PLL7_CTRL		0x10
+#define BM_PLL_ENABLE		(0x1 << 13)
+#define BM_PLL_LOCK		(0x1 << 31)
+
+#define VF610_SUSPEND_OCRAM_SIZE	0x4000
+
+#define VF_UART0_BASE_ADDR	0x40027000
+#define VF_UART1_BASE_ADDR	0x40028000
+#define VF_UART2_BASE_ADDR	0x40029000
+#define VF_UART3_BASE_ADDR	0x4002a000
+#define VF_UART_BASE_ADDR(n)	VF_UART##n##_BASE_ADDR
+#define VF_UART_BASE(n)		VF_UART_BASE_ADDR(n)
+#define VF_UART_PHYSICAL_BASE	VF_UART_BASE(CONFIG_DEBUG_VF_UART_PORT)
+
+static void __iomem *ccm_base;
+static void __iomem *suspend_ocram_base;
+
+/*
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ *                              .
+ *                              .
+ *                              .
+ *                              ^
+ *                              ^
+ *                              ^
+ *                      vf610_suspend code
+ *              PM_INFO structure(vf610_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+struct vf610_pm_base {
+	phys_addr_t pbase;
+	void __iomem *vbase;
+};
+
+struct vf610_pm_socdata {
+	const char *src_compat;
+	const char *gpc_compat;
+	const char *anatop_compat;
+};
+
+static const struct vf610_pm_socdata vf610_pm_data __initconst = {
+	.src_compat = "fsl,vf610-src",
+	.gpc_compat = "fsl,vf610-gpc",
+	.anatop_compat = "fsl,vf610-anatop",
+};
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * suspend code(arch/arm/mach-imx/suspend-vf610.S), if this struct
+ * definition is changed, the offset definition in
+ * arch/arm/mach-imx/suspend-vf610.S must be also changed accordingly,
+ * otherwise, the suspend to ocram function will be broken!
+ */
+struct vf610_cpu_pm_info {
+	phys_addr_t pbase; /* The physical address of pm_info. */
+	phys_addr_t resume_addr; /* The physical resume address for asm code */
+	u32 cpu_type; /* Currently not used, leave it for alignment */
+	u32 pm_info_size; /* Size of pm_info. */
+	struct vf610_pm_base anatop_base;
+	struct vf610_pm_base src_base;
+	struct vf610_pm_base ccm_base;
+	struct vf610_pm_base gpc_base;
+	struct vf610_pm_base l2_base;
+} __aligned(8);
+
+#ifdef DEBUG
+static void uart_reinit(unsigned long int rate, unsigned long int baud)
+{
+	void __iomem *membase = ioremap(VF_UART_PHYSICAL_BASE, 0x1000);
+	u8 tmp;
+	u16 sbr, brfa;
+
+	/* UART_C2 */
+	__raw_writeb(0, membase + 0x3);
+
+	sbr = (u16) (rate / (baud * 16));
+	brfa = (rate / baud) - (sbr * 16);
+
+	tmp = ((sbr & 0x1f00) >> 8);
+	__raw_writeb(tmp, membase + 0x0);
+	tmp = sbr & 0x00ff;
+	__raw_writeb(tmp, membase + 0x1);
+
+	/* UART_C4 */
+	__raw_writeb(brfa & 0xf, membase + 0xa);
+
+	/* UART_C2 */
+	__raw_writeb(0xac, membase + 0x3);
+
+	iounmap(membase);
+}
+#else
+static void uart_reinit(unsigned long int rate, unsigned long int baud) {}
+#endif
+
+static void vf610_enable_pll(void __iomem *pll_base)
+{
+	writel_relaxed(readl_relaxed(pll_base) | BM_PLL_ENABLE, pll_base);
+}
+
+static void vf610_disable_pll(void __iomem *pll_base)
+{
+	writel_relaxed(readl_relaxed(pll_base) & ~BM_PLL_ENABLE, pll_base);
+}
+
+int vf610_set_lpm(enum vf610_cpu_pwr_mode mode)
+{
+	u32 ccr = readl_relaxed(ccm_base + CCR);
+	u32 ccsr = readl_relaxed(ccm_base + CCSR);
+	u32 cclpcr = readl_relaxed(ccm_base + CLPCR);
+	struct vf610_cpu_pm_info *pm_info = suspend_ocram_base;
+	void __iomem *gpc_base = pm_info->gpc_base.vbase;
+	u32 gpc_pgcr = readl_relaxed(gpc_base + GPC_PGCR);
+	void __iomem *anatop = pm_info->anatop_base.vbase;
+
+	switch (mode) {
+	case VF610_STOP:
+		cclpcr &= ~BM_CLPCR_ANADIG_STOP_MODE;
+		cclpcr |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
+		cclpcr &= ~BM_CLPCR_SBYOS;
+		writel_relaxed(cclpcr, ccm_base + CLPCR);
+
+		gpc_pgcr |= BM_PGCR_DS_STOP;
+		gpc_pgcr |= BM_PGCR_HP_OFF;
+		writel_relaxed(gpc_pgcr, gpc_base + GPC_PGCR);
+
+		writel_relaxed(BM_LPMR_STOP, gpc_base + GPC_LPMR);
+		/* fall-through */
+	case VF610_LP_RUN:
+		ccr |= BM_CCR_FIRC_EN;
+		writel_relaxed(ccr, ccm_base + CCR);
+
+		/* Switch internal OSC's */
+		ccsr &= ~BM_CCSR_FAST_CLK_SEL;
+		ccsr &= ~BM_CCSR_SLOW_CLK_SEL;
+		writel_relaxed(ccsr, ccm_base + CCSR);
+
+		ccsr &= ~BM_CCSR_SYS_CLK_SEL_MASK;
+		writel_relaxed(ccsr, ccm_base + CCSR);
+		uart_reinit(4000000UL, 115200);
+
+		vf610_disable_pll(anatop + ANATOP_PLL1_CTRL);
+		vf610_disable_pll(anatop + ANATOP_PLL3_CTRL);
+		vf610_disable_pll(anatop + ANATOP_PLL5_CTRL);
+		vf610_disable_pll(anatop + ANATOP_PLL7_CTRL);
+		break;
+	case VF610_RUN:
+		vf610_enable_pll(anatop + ANATOP_PLL1_CTRL);
+		vf610_enable_pll(anatop + ANATOP_PLL3_CTRL);
+		vf610_enable_pll(anatop + ANATOP_PLL5_CTRL);
+		vf610_enable_pll(anatop + ANATOP_PLL7_CTRL);
+
+		ccsr &= ~BM_CCSR_SYS_CLK_SEL_MASK;
+		ccsr |= 0x4;
+		writel_relaxed(ccsr, ccm_base + CCSR);
+		uart_reinit(83368421UL, 115200);
+
+		writel_relaxed(BM_LPMR_RUN, gpc_base + GPC_LPMR);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vf610_pm_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		vf610_set_lpm(VF610_LP_RUN);
+		imx_gpc_pre_suspend(false);
+
+		/* zzZZZzzz */
+		cpu_do_idle();
+
+		imx_gpc_post_resume();
+		vf610_set_lpm(VF610_RUN);
+		break;
+	case PM_SUSPEND_MEM:
+		vf610_set_lpm(VF610_STOP);
+		imx_gpc_pre_suspend(false);
+
+		cpu_do_idle();
+
+		imx_gpc_post_resume();
+		vf610_set_lpm(VF610_RUN);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vf610_pm_valid(suspend_state_t state)
+{
+	return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
+}
+
+static const struct platform_suspend_ops vf610_pm_ops = {
+	.enter = vf610_pm_enter,
+	.valid = vf610_pm_valid,
+};
+
+void __init vf610_pm_set_ccm_base(void __iomem *base)
+{
+	ccm_base = base;
+}
+
+static int __init imx_pm_get_base(struct vf610_pm_base *base,
+				const char *compat)
+{
+	struct device_node *node;
+	struct resource res;
+	int ret = 0;
+
+	node = of_find_compatible_node(NULL, NULL, compat);
+	if (!node) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret)
+		goto put_node;
+
+	base->pbase = res.start;
+	base->vbase = ioremap(res.start, resource_size(&res));
+
+	if (!base->vbase)
+		ret = -ENOMEM;
+
+put_node:
+	of_node_put(node);
+out:
+	return ret;
+}
+
+static int __init vf610_suspend_init(const struct vf610_pm_socdata *socdata)
+{
+	phys_addr_t ocram_pbase;
+	struct device_node *node;
+	struct platform_device *pdev;
+	struct vf610_cpu_pm_info *pm_info;
+	struct gen_pool *ocram_pool;
+	unsigned long ocram_base;
+	int ret = 0;
+
+	suspend_set_ops(&vf610_pm_ops);
+
+	if (!socdata) {
+		pr_warn("%s: invalid argument!\n", __func__);
+		return -EINVAL;
+	}
+
+	node = of_find_compatible_node(NULL, NULL, "mmio-sram");
+	if (!node) {
+		pr_warn("%s: failed to find ocram node!\n", __func__);
+		return -ENODEV;
+	}
+
+	pdev = of_find_device_by_node(node);
+	if (!pdev) {
+		pr_warn("%s: failed to find ocram device!\n", __func__);
+		ret = -ENODEV;
+		goto put_node;
+	}
+
+	ocram_pool = dev_get_gen_pool(&pdev->dev);
+	if (!ocram_pool) {
+		pr_warn("%s: ocram pool unavailable!\n", __func__);
+		ret = -ENODEV;
+		goto put_node;
+	}
+
+	ocram_base = gen_pool_alloc(ocram_pool, VF610_SUSPEND_OCRAM_SIZE);
+	if (!ocram_base) {
+		pr_warn("%s: unable to alloc ocram!\n", __func__);
+		ret = -ENOMEM;
+		goto put_node;
+	}
+
+	ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
+
+	suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
+		VF610_SUSPEND_OCRAM_SIZE, false);
+
+	pm_info = suspend_ocram_base;
+	pm_info->pbase = ocram_pbase;
+	pm_info->pm_info_size = sizeof(*pm_info);
+
+	/*
+	 * ccm physical address is not used by asm code currently,
+	 * so get ccm virtual address directly, as we already have
+	 * it from ccm driver.
+	 */
+	pm_info->ccm_base.vbase = ccm_base;
+
+	ret = imx_pm_get_base(&pm_info->anatop_base, socdata->anatop_compat);
+	if (ret) {
+		pr_warn("%s: failed to get anatop base %d!\n", __func__, ret);
+		goto put_node;
+	}
+
+	ret = imx_pm_get_base(&pm_info->src_base, socdata->src_compat);
+	if (ret) {
+		pr_warn("%s: failed to get src base %d!\n", __func__, ret);
+		goto src_map_failed;
+	}
+
+	ret = imx_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
+	if (ret) {
+		pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
+		goto gpc_map_failed;
+	}
+
+	ret = imx_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
+	if (ret) {
+		pr_warn("%s: failed to get pl310-cache base %d!\n",
+			__func__, ret);
+		goto pl310_cache_map_failed;
+	}
+
+	goto put_node;
+
+pl310_cache_map_failed:
+	iounmap(&pm_info->gpc_base.vbase);
+gpc_map_failed:
+	iounmap(&pm_info->src_base.vbase);
+src_map_failed:
+	iounmap(&pm_info->anatop_base.vbase);
+put_node:
+	of_node_put(node);
+
+	return ret;
+}
+
+void __init vf610_pm_init(void)
+{
+	int ret;
+
+	WARN_ON(!ccm_base);
+
+	if (IS_ENABLED(CONFIG_SUSPEND)) {
+		ret = vf610_suspend_init(&vf610_pm_data);
+		if (ret)
+			pr_warn("%s: No DDR LPM support with suspend %d!\n",
+				__func__, ret);
+	}
+}
+
-- 
2.1.0

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

* [PATCH 9/9] ARM: vf610: initial suspend/resume support
@ 2014-09-22 17:09   ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds initial suspend/resume support for Vybrid SoC.
The standby sleep state puts the module in LP-RUN mode which
allows to the SoC to be woken by a regular interrupt. The mem
sleep state (Suspend-to-RAM) uses the STOP mode which puts the
memory in self-refresh mode but keeps the memory clock enabled.
To wake the SoC a power management wakeup IRQ need to be enabled
using irq_set_irq_wake (e.g. through a GPIO).

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 arch/arm/mach-imx/Makefile     |   1 +
 arch/arm/mach-imx/clk-vf610.c  |   3 +
 arch/arm/mach-imx/common.h     |  10 +
 arch/arm/mach-imx/mach-vf610.c |   1 +
 arch/arm/mach-imx/pm-vf610.c   | 428 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 443 insertions(+)
 create mode 100644 arch/arm/mach-imx/pm-vf610.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 6e4fcd8..0f558aa 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -103,6 +103,7 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
 endif
 obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
+obj-$(CONFIG_SOC_VF610) += pm-vf610.o
 
 obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
 obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
index 1034e78..fbaa708 100644
--- a/arch/arm/mach-imx/clk-vf610.c
+++ b/arch/arm/mach-imx/clk-vf610.c
@@ -13,6 +13,7 @@
 #include <dt-bindings/clock/vf610-clock.h>
 
 #include "clk.h"
+#include "common.h"
 
 #define CCM_CCR			(ccm_base + 0x00)
 #define CCM_CSR			(ccm_base + 0x04)
@@ -131,6 +132,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 	ccm_base = of_iomap(np, 0);
 	BUG_ON(!ccm_base);
 
+	vf610_pm_set_ccm_base(ccm_base);
+
 	clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels));
 	clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels));
 
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index ca7a0d9..6dd360f 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -80,6 +80,13 @@ enum mxc_cpu_pwr_mode {
 	STOP_POWER_OFF,		/* STOP + SRPG */
 };
 
+enum vf610_cpu_pwr_mode {
+	VF610_RUN,
+	VF610_LP_RUN,
+	VF610_STOP,
+	VF610_LP_STOP,
+};
+
 enum mx3_cpu_pwr_mode {
 	MX3_RUN,
 	MX3_WAIT,
@@ -125,6 +132,7 @@ int imx_cpu_kill(unsigned int cpu);
 #ifdef CONFIG_SUSPEND
 void v7_cpu_resume(void);
 void imx6_suspend(void __iomem *ocram_vbase);
+void vf610_suspend(void);
 #else
 static inline void v7_cpu_resume(void) {}
 static inline void imx6_suspend(void __iomem *ocram_vbase) {}
@@ -135,6 +143,8 @@ void imx6dl_pm_init(void);
 void imx6sl_pm_init(void);
 void imx6sx_pm_init(void);
 void imx6q_pm_set_ccm_base(void __iomem *base);
+void vf610_pm_init(void);
+void vf610_pm_set_ccm_base(void __iomem *base);
 
 #ifdef CONFIG_PM
 void imx51_pm_init(void);
diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c
index eef3496..79f0461 100644
--- a/arch/arm/mach-imx/mach-vf610.c
+++ b/arch/arm/mach-imx/mach-vf610.c
@@ -25,6 +25,7 @@ static void __init vf610_init_machine(void)
 {
 	mxc_arch_reset_init_dt();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+	vf610_pm_init();
 }
 
 static const char * const vf610_dt_compat[] __initconst = {
diff --git a/arch/arm/mach-imx/pm-vf610.c b/arch/arm/mach-imx/pm-vf610.c
new file mode 100644
index 0000000..87dbbac
--- /dev/null
+++ b/arch/arm/mach-imx/pm-vf610.c
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2014 Toradex AG
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/genalloc.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <linux/clk.h>
+#include <asm/cacheflush.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/tlb.h>
+
+#include "common.h"
+
+#define CCR				0x0
+#define BM_CCR_FIRC_EN			(0x1 << 16)
+#define BM_CCR_FXOSC_EN			(0x1 << 12)
+
+#define CCSR				0x8
+#define BM_CCSR_DDRC_CLK_SEL		(0x1 << 6)
+#define BM_CCSR_FAST_CLK_SEL		(0x1 << 5)
+#define BM_CCSR_SLOW_CLK_SEL		(0x1 << 4)
+#define BM_CCSR_SYS_CLK_SEL_MASK	(0x7 << 0)
+
+#define CLPCR				0x2c
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM	(0x1 << 5)
+#define BM_CLPCR_SBYOS			(0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC		(0x1 << 7)
+#define BM_CLPCR_ANADIG_STOP_MODE	(0x1 << 8)
+#define BM_CLPCR_FXOSC_BYPSEN		(0x1 << 10)
+#define BM_CLPCR_FXOSC_PWRDWN		(0x1 << 11)
+#define BM_CLPCR_MASK_CORE0_WFI		(0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI		(0x1 << 23)
+#define BM_CLPCR_MASK_SCU_IDLE		(0x1 << 24)
+#define BM_CLPCR_MASK_L2CC_IDLE		(0x1 << 25)
+
+#define CGPR				0x64
+#define BM_CGPR_INT_MEM_CLK_LPM		(0x1 << 17)
+
+#define GPC_PGCR			0x0
+#define BM_PGCR_DS_STOP			(0x1 << 7)
+#define BM_PGCR_DS_LPSTOP		(0x1 << 6)
+#define BM_PGCR_WB_STOP			(0x1 << 4)
+#define BM_PGCR_HP_OFF			(0x1 << 3)
+
+#define GPC_LPMR			0x40
+#define BM_LPMR_RUN			0x0
+#define BM_LPMR_STOP			0x2
+
+#define ANATOP_PLL1_CTRL		0x270
+#define ANATOP_PLL2_CTRL		0x30
+#define ANATOP_PLL3_CTRL		0x10
+#define ANATOP_PLL4_CTRL		0x70
+#define ANATOP_PLL5_CTRL		0xe0
+#define ANATOP_PLL6_CTRL		0xa0
+#define ANATOP_PLL7_CTRL		0x10
+#define BM_PLL_ENABLE		(0x1 << 13)
+#define BM_PLL_LOCK		(0x1 << 31)
+
+#define VF610_SUSPEND_OCRAM_SIZE	0x4000
+
+#define VF_UART0_BASE_ADDR	0x40027000
+#define VF_UART1_BASE_ADDR	0x40028000
+#define VF_UART2_BASE_ADDR	0x40029000
+#define VF_UART3_BASE_ADDR	0x4002a000
+#define VF_UART_BASE_ADDR(n)	VF_UART##n##_BASE_ADDR
+#define VF_UART_BASE(n)		VF_UART_BASE_ADDR(n)
+#define VF_UART_PHYSICAL_BASE	VF_UART_BASE(CONFIG_DEBUG_VF_UART_PORT)
+
+static void __iomem *ccm_base;
+static void __iomem *suspend_ocram_base;
+
+/*
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ *                              .
+ *                              .
+ *                              .
+ *                              ^
+ *                              ^
+ *                              ^
+ *                      vf610_suspend code
+ *              PM_INFO structure(vf610_cpu_pm_info)
+ * ======================== low address =======================
+ */
+
+struct vf610_pm_base {
+	phys_addr_t pbase;
+	void __iomem *vbase;
+};
+
+struct vf610_pm_socdata {
+	const char *src_compat;
+	const char *gpc_compat;
+	const char *anatop_compat;
+};
+
+static const struct vf610_pm_socdata vf610_pm_data __initconst = {
+	.src_compat = "fsl,vf610-src",
+	.gpc_compat = "fsl,vf610-gpc",
+	.anatop_compat = "fsl,vf610-anatop",
+};
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * suspend code(arch/arm/mach-imx/suspend-vf610.S), if this struct
+ * definition is changed, the offset definition in
+ * arch/arm/mach-imx/suspend-vf610.S must be also changed accordingly,
+ * otherwise, the suspend to ocram function will be broken!
+ */
+struct vf610_cpu_pm_info {
+	phys_addr_t pbase; /* The physical address of pm_info. */
+	phys_addr_t resume_addr; /* The physical resume address for asm code */
+	u32 cpu_type; /* Currently not used, leave it for alignment */
+	u32 pm_info_size; /* Size of pm_info. */
+	struct vf610_pm_base anatop_base;
+	struct vf610_pm_base src_base;
+	struct vf610_pm_base ccm_base;
+	struct vf610_pm_base gpc_base;
+	struct vf610_pm_base l2_base;
+} __aligned(8);
+
+#ifdef DEBUG
+static void uart_reinit(unsigned long int rate, unsigned long int baud)
+{
+	void __iomem *membase = ioremap(VF_UART_PHYSICAL_BASE, 0x1000);
+	u8 tmp;
+	u16 sbr, brfa;
+
+	/* UART_C2 */
+	__raw_writeb(0, membase + 0x3);
+
+	sbr = (u16) (rate / (baud * 16));
+	brfa = (rate / baud) - (sbr * 16);
+
+	tmp = ((sbr & 0x1f00) >> 8);
+	__raw_writeb(tmp, membase + 0x0);
+	tmp = sbr & 0x00ff;
+	__raw_writeb(tmp, membase + 0x1);
+
+	/* UART_C4 */
+	__raw_writeb(brfa & 0xf, membase + 0xa);
+
+	/* UART_C2 */
+	__raw_writeb(0xac, membase + 0x3);
+
+	iounmap(membase);
+}
+#else
+static void uart_reinit(unsigned long int rate, unsigned long int baud) {}
+#endif
+
+static void vf610_enable_pll(void __iomem *pll_base)
+{
+	writel_relaxed(readl_relaxed(pll_base) | BM_PLL_ENABLE, pll_base);
+}
+
+static void vf610_disable_pll(void __iomem *pll_base)
+{
+	writel_relaxed(readl_relaxed(pll_base) & ~BM_PLL_ENABLE, pll_base);
+}
+
+int vf610_set_lpm(enum vf610_cpu_pwr_mode mode)
+{
+	u32 ccr = readl_relaxed(ccm_base + CCR);
+	u32 ccsr = readl_relaxed(ccm_base + CCSR);
+	u32 cclpcr = readl_relaxed(ccm_base + CLPCR);
+	struct vf610_cpu_pm_info *pm_info = suspend_ocram_base;
+	void __iomem *gpc_base = pm_info->gpc_base.vbase;
+	u32 gpc_pgcr = readl_relaxed(gpc_base + GPC_PGCR);
+	void __iomem *anatop = pm_info->anatop_base.vbase;
+
+	switch (mode) {
+	case VF610_STOP:
+		cclpcr &= ~BM_CLPCR_ANADIG_STOP_MODE;
+		cclpcr |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
+		cclpcr &= ~BM_CLPCR_SBYOS;
+		writel_relaxed(cclpcr, ccm_base + CLPCR);
+
+		gpc_pgcr |= BM_PGCR_DS_STOP;
+		gpc_pgcr |= BM_PGCR_HP_OFF;
+		writel_relaxed(gpc_pgcr, gpc_base + GPC_PGCR);
+
+		writel_relaxed(BM_LPMR_STOP, gpc_base + GPC_LPMR);
+		/* fall-through */
+	case VF610_LP_RUN:
+		ccr |= BM_CCR_FIRC_EN;
+		writel_relaxed(ccr, ccm_base + CCR);
+
+		/* Switch internal OSC's */
+		ccsr &= ~BM_CCSR_FAST_CLK_SEL;
+		ccsr &= ~BM_CCSR_SLOW_CLK_SEL;
+		writel_relaxed(ccsr, ccm_base + CCSR);
+
+		ccsr &= ~BM_CCSR_SYS_CLK_SEL_MASK;
+		writel_relaxed(ccsr, ccm_base + CCSR);
+		uart_reinit(4000000UL, 115200);
+
+		vf610_disable_pll(anatop + ANATOP_PLL1_CTRL);
+		vf610_disable_pll(anatop + ANATOP_PLL3_CTRL);
+		vf610_disable_pll(anatop + ANATOP_PLL5_CTRL);
+		vf610_disable_pll(anatop + ANATOP_PLL7_CTRL);
+		break;
+	case VF610_RUN:
+		vf610_enable_pll(anatop + ANATOP_PLL1_CTRL);
+		vf610_enable_pll(anatop + ANATOP_PLL3_CTRL);
+		vf610_enable_pll(anatop + ANATOP_PLL5_CTRL);
+		vf610_enable_pll(anatop + ANATOP_PLL7_CTRL);
+
+		ccsr &= ~BM_CCSR_SYS_CLK_SEL_MASK;
+		ccsr |= 0x4;
+		writel_relaxed(ccsr, ccm_base + CCSR);
+		uart_reinit(83368421UL, 115200);
+
+		writel_relaxed(BM_LPMR_RUN, gpc_base + GPC_LPMR);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vf610_pm_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		vf610_set_lpm(VF610_LP_RUN);
+		imx_gpc_pre_suspend(false);
+
+		/* zzZZZzzz */
+		cpu_do_idle();
+
+		imx_gpc_post_resume();
+		vf610_set_lpm(VF610_RUN);
+		break;
+	case PM_SUSPEND_MEM:
+		vf610_set_lpm(VF610_STOP);
+		imx_gpc_pre_suspend(false);
+
+		cpu_do_idle();
+
+		imx_gpc_post_resume();
+		vf610_set_lpm(VF610_RUN);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vf610_pm_valid(suspend_state_t state)
+{
+	return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
+}
+
+static const struct platform_suspend_ops vf610_pm_ops = {
+	.enter = vf610_pm_enter,
+	.valid = vf610_pm_valid,
+};
+
+void __init vf610_pm_set_ccm_base(void __iomem *base)
+{
+	ccm_base = base;
+}
+
+static int __init imx_pm_get_base(struct vf610_pm_base *base,
+				const char *compat)
+{
+	struct device_node *node;
+	struct resource res;
+	int ret = 0;
+
+	node = of_find_compatible_node(NULL, NULL, compat);
+	if (!node) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret)
+		goto put_node;
+
+	base->pbase = res.start;
+	base->vbase = ioremap(res.start, resource_size(&res));
+
+	if (!base->vbase)
+		ret = -ENOMEM;
+
+put_node:
+	of_node_put(node);
+out:
+	return ret;
+}
+
+static int __init vf610_suspend_init(const struct vf610_pm_socdata *socdata)
+{
+	phys_addr_t ocram_pbase;
+	struct device_node *node;
+	struct platform_device *pdev;
+	struct vf610_cpu_pm_info *pm_info;
+	struct gen_pool *ocram_pool;
+	unsigned long ocram_base;
+	int ret = 0;
+
+	suspend_set_ops(&vf610_pm_ops);
+
+	if (!socdata) {
+		pr_warn("%s: invalid argument!\n", __func__);
+		return -EINVAL;
+	}
+
+	node = of_find_compatible_node(NULL, NULL, "mmio-sram");
+	if (!node) {
+		pr_warn("%s: failed to find ocram node!\n", __func__);
+		return -ENODEV;
+	}
+
+	pdev = of_find_device_by_node(node);
+	if (!pdev) {
+		pr_warn("%s: failed to find ocram device!\n", __func__);
+		ret = -ENODEV;
+		goto put_node;
+	}
+
+	ocram_pool = dev_get_gen_pool(&pdev->dev);
+	if (!ocram_pool) {
+		pr_warn("%s: ocram pool unavailable!\n", __func__);
+		ret = -ENODEV;
+		goto put_node;
+	}
+
+	ocram_base = gen_pool_alloc(ocram_pool, VF610_SUSPEND_OCRAM_SIZE);
+	if (!ocram_base) {
+		pr_warn("%s: unable to alloc ocram!\n", __func__);
+		ret = -ENOMEM;
+		goto put_node;
+	}
+
+	ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
+
+	suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
+		VF610_SUSPEND_OCRAM_SIZE, false);
+
+	pm_info = suspend_ocram_base;
+	pm_info->pbase = ocram_pbase;
+	pm_info->pm_info_size = sizeof(*pm_info);
+
+	/*
+	 * ccm physical address is not used by asm code currently,
+	 * so get ccm virtual address directly, as we already have
+	 * it from ccm driver.
+	 */
+	pm_info->ccm_base.vbase = ccm_base;
+
+	ret = imx_pm_get_base(&pm_info->anatop_base, socdata->anatop_compat);
+	if (ret) {
+		pr_warn("%s: failed to get anatop base %d!\n", __func__, ret);
+		goto put_node;
+	}
+
+	ret = imx_pm_get_base(&pm_info->src_base, socdata->src_compat);
+	if (ret) {
+		pr_warn("%s: failed to get src base %d!\n", __func__, ret);
+		goto src_map_failed;
+	}
+
+	ret = imx_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
+	if (ret) {
+		pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
+		goto gpc_map_failed;
+	}
+
+	ret = imx_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
+	if (ret) {
+		pr_warn("%s: failed to get pl310-cache base %d!\n",
+			__func__, ret);
+		goto pl310_cache_map_failed;
+	}
+
+	goto put_node;
+
+pl310_cache_map_failed:
+	iounmap(&pm_info->gpc_base.vbase);
+gpc_map_failed:
+	iounmap(&pm_info->src_base.vbase);
+src_map_failed:
+	iounmap(&pm_info->anatop_base.vbase);
+put_node:
+	of_node_put(node);
+
+	return ret;
+}
+
+void __init vf610_pm_init(void)
+{
+	int ret;
+
+	WARN_ON(!ccm_base);
+
+	if (IS_ENABLED(CONFIG_SUSPEND)) {
+		ret = vf610_suspend_init(&vf610_pm_data);
+		if (ret)
+			pr_warn("%s: No DDR LPM support with suspend %d!\n",
+				__func__, ret);
+	}
+}
+
-- 
2.1.0

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

* [PATCH 0/9] ARM: vf610: Suspend/resume support
  2014-09-22 17:09 ` Stefan Agner
                   ` (9 preceding siblings ...)
  (?)
@ 2014-09-23 15:36 ` Bill Pringlemeir
  2014-09-24  8:22   ` Stefan Agner
  -1 siblings, 1 reply; 52+ messages in thread
From: Bill Pringlemeir @ 2014-09-23 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 22 Sep 2014, stefan at agner.ch wrote:

> This patchset provides suspend/resume support for Freescale Vybrid
> SoC (vf610). The code is generally aligned to the implementation
> for i.MX6. The subsystems SRC and GPC need some changes to support
> the Vybrid specific implementation.
>
> This patchset relies on GPIO driver to be present (in order to
> provide a wakeup source) as well as using the ARM Global Timer
> clock source (the Vybrid specifc PIT clock source, vf_pit_timer.c
> does not support shutdown).
>
> The implemented sleep states (LP-RUN and STOP), are not the most
> power saving functions available on Vybrid. Especially for
> suspend-to-memory one of the LPSTOP modes looks more appropriate.
> However, the complexity is somewhat higher (we would need to move
> execution path to SRAM and store IOMUX and DDRMC configuration).
> Currently, I have not the resources to look into that so I hope
> that this initial code qualifies as power saving functions to be
> applied.
>
> Suspend-to-memory as well as standby mode is tested on Colibri
> VF61.

> Power measurement (Colibri VF61, whole module):
> - Idle: 540mW
> - LP-RUN: 220mW (standby)
> - STOP: 200mW (mem)

> Stefan Agner (9):
> ARM: dts: vf610: Add system reset controller (SRC)
> ARM: dts: vf610: add global power controller (GPC)
> ARM: dts: vf610: add on-chip SRAM

These above three change sets have some implications for dual-chip
(Cortex-A5/Cortex-M4) configurations.  Epecially those running MQX.
There is not harm to define the register space (except DT size).
However, if you activate drivers that manipulate the registers for all
systems, then there is no choice to have MQX work on the 2nd core.

I think that Shawn Guo already did a patchset to remove stuff from the
vf610.dtsi to the machine/configuration DT files.

> ARM: dts: vf610-colibri: GPIO power key
> gpio: vf610: Extend with wakeup support
> ARM: imx: gpc: Support vf610 global power controller
> ARM: imx: src: Support vf610 system reset controller
> ARM: imx: clk-gate2: allow custom gate configuration
> ARM: vf610: initial suspend/resume support
>
> arch/arm/boot/dts/vf610-colibri-eval-v3.dts | 26 ++
> arch/arm/boot/dts/vf610.dtsi | 33 +++ arch/arm/mach-imx/Kconfig | 2 +
> arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/clk-gate2.c | 7 +-
> arch/arm/mach-imx/clk-vf610.c | 6 + arch/arm/mach-imx/clk.h | 13 +-
> arch/arm/mach-imx/common.h | 14 +- arch/arm/mach-imx/gpc.c | 61 ++--
> arch/arm/mach-imx/mach-imx6q.c | 2 +- arch/arm/mach-imx/mach-imx6sl.c
> | 2 +- arch/arm/mach-imx/mach-vf610.c | 9 +
> arch/arm/mach-imx/pm-vf610.c | 428 ++++++++++++++++++++++++++++
> arch/arm/mach-imx/src.c | 11 + drivers/gpio/gpio-vf610.c | 16 ++
> include/dt-bindings/clock/vf610-clock.h | 3 +- 16 files changed, 605
> insertions(+), 29 deletions(-) create mode 100644
> arch/arm/mach-imx/pm-vf610.c

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

* [PATCH 0/9] ARM: vf610: Suspend/resume support
  2014-09-23 15:36 ` [PATCH 0/9] ARM: vf610: Suspend/resume support Bill Pringlemeir
@ 2014-09-24  8:22   ` Stefan Agner
  2014-09-24 16:33     ` Bill Pringlemeir
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Agner @ 2014-09-24  8:22 UTC (permalink / raw)
  To: linux-arm-kernel

Am 2014-09-23 17:36, schrieb Bill Pringlemeir:
> On 22 Sep 2014, stefan at agner.ch wrote:
> 
>> This patchset provides suspend/resume support for Freescale Vybrid
>> SoC (vf610). The code is generally aligned to the implementation
>> for i.MX6. The subsystems SRC and GPC need some changes to support
>> the Vybrid specific implementation.
>>
>> This patchset relies on GPIO driver to be present (in order to
>> provide a wakeup source) as well as using the ARM Global Timer
>> clock source (the Vybrid specifc PIT clock source, vf_pit_timer.c
>> does not support shutdown).
>>
>> The implemented sleep states (LP-RUN and STOP), are not the most
>> power saving functions available on Vybrid. Especially for
>> suspend-to-memory one of the LPSTOP modes looks more appropriate.
>> However, the complexity is somewhat higher (we would need to move
>> execution path to SRAM and store IOMUX and DDRMC configuration).
>> Currently, I have not the resources to look into that so I hope
>> that this initial code qualifies as power saving functions to be
>> applied.
>>
>> Suspend-to-memory as well as standby mode is tested on Colibri
>> VF61.
> 
>> Power measurement (Colibri VF61, whole module):
>> - Idle: 540mW
>> - LP-RUN: 220mW (standby)
>> - STOP: 200mW (mem)
> 
>> Stefan Agner (9):
>> ARM: dts: vf610: Add system reset controller (SRC)
>> ARM: dts: vf610: add global power controller (GPC)
>> ARM: dts: vf610: add on-chip SRAM
> 
> These above three change sets have some implications for dual-chip
> (Cortex-A5/Cortex-M4) configurations.  Epecially those running MQX.
> There is not harm to define the register space (except DT size).
> However, if you activate drivers that manipulate the registers for all
> systems, then there is no choice to have MQX work on the 2nd core.

On the Timesys BSP, the kernel is fiddling around with this registers
too, and AFAIK MQX is working with that kernel. Is MQX really using the
GPC and SRC modules? I thought MQX is just relying on Linux taking care
of that.

Also, you have this problem with other registers as well, for instance
the CCM module. In fact, to get into deeper sleep modes, you need to
access the GPC (global power controller) as well as the CCM (clock
controller module, for instance the CCM_CLPCR register). When you look
at all the entry sequences, they all fiddling around with the GPC and
the CCM. And I don't think that the kernel can work properly without
having control over the clock module.

IMHO, the SRC and GPC are like the CCM, and need to be under control of
Linux exclusively.

Another case is the SRAM. There are other peripherals which are much
more important, e.g. both instances of the EDMA modules are currently
unconditional part of the device tree.

Besides, afaik you can also use status = "disabled" in a device tree
including the vf610.dtsi. The device tree is parsed sequential, the last
settings wins.

> 
> I think that Shawn Guo already did a patchset to remove stuff from the
> vf610.dtsi to the machine/configuration DT files.
> 
>> ARM: dts: vf610-colibri: GPIO power key
>> gpio: vf610: Extend with wakeup support
>> ARM: imx: gpc: Support vf610 global power controller
>> ARM: imx: src: Support vf610 system reset controller
>> ARM: imx: clk-gate2: allow custom gate configuration
>> ARM: vf610: initial suspend/resume support
>>
>> arch/arm/boot/dts/vf610-colibri-eval-v3.dts | 26 ++
>> arch/arm/boot/dts/vf610.dtsi | 33 +++ arch/arm/mach-imx/Kconfig | 2 +
>> arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/clk-gate2.c | 7 +-
>> arch/arm/mach-imx/clk-vf610.c | 6 + arch/arm/mach-imx/clk.h | 13 +-
>> arch/arm/mach-imx/common.h | 14 +- arch/arm/mach-imx/gpc.c | 61 ++--
>> arch/arm/mach-imx/mach-imx6q.c | 2 +- arch/arm/mach-imx/mach-imx6sl.c
>> | 2 +- arch/arm/mach-imx/mach-vf610.c | 9 +
>> arch/arm/mach-imx/pm-vf610.c | 428 ++++++++++++++++++++++++++++
>> arch/arm/mach-imx/src.c | 11 + drivers/gpio/gpio-vf610.c | 16 ++
>> include/dt-bindings/clock/vf610-clock.h | 3 +- 16 files changed, 605
>> insertions(+), 29 deletions(-) create mode 100644
>> arch/arm/mach-imx/pm-vf610.c

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

* Re: [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
  2014-09-22 17:09   ` Stefan Agner
  (?)
@ 2014-09-24  9:16     ` Linus Walleij
  -1 siblings, 0 replies; 52+ messages in thread
From: Linus Walleij @ 2014-09-24  9:16 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Shawn Guo, Sascha Hauer, Alexandre Courbot,
	Russell King - ARM Linux, jingchang.lu, Huang Yongcai-B20788,
	linux-arm-kernel, linux-kernel, linux-gpio

On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:

> Add device tree property for system reset controller.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Are there already device tree bindings for SRC and GRC?

Yours,
Linus Walleij

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

* Re: [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
@ 2014-09-24  9:16     ` Linus Walleij
  0 siblings, 0 replies; 52+ messages in thread
From: Linus Walleij @ 2014-09-24  9:16 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Shawn Guo, Sascha Hauer, Alexandre Courbot,
	Russell King - ARM Linux, jingchang.lu, Huang Yongcai-B20788,
	linux-arm-kernel, linux-kernel, linux-gpio

On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:

> Add device tree property for system reset controller.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Are there already device tree bindings for SRC and GRC?

Yours,
Linus Walleij

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

* [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
@ 2014-09-24  9:16     ` Linus Walleij
  0 siblings, 0 replies; 52+ messages in thread
From: Linus Walleij @ 2014-09-24  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:

> Add device tree property for system reset controller.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Are there already device tree bindings for SRC and GRC?

Yours,
Linus Walleij

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

* Re: [PATCH 5/9] gpio: vf610: Extend with wakeup support
  2014-09-22 17:09   ` Stefan Agner
  (?)
@ 2014-09-24  9:19     ` Linus Walleij
  -1 siblings, 0 replies; 52+ messages in thread
From: Linus Walleij @ 2014-09-24  9:19 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Shawn Guo, Sascha Hauer, Alexandre Courbot,
	Russell King - ARM Linux, jingchang.lu, Huang Yongcai-B20788,
	linux-arm-kernel, linux-kernel, linux-gpio

On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:

> Support Vybrid GPIO's as wakeup source by requesting the parent
> IRQ as wakeup IRQ.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++

This driver is not yet upstream. Make wakeup support part
of the initial driver submission instead, it doesn't hurt.

Yours,
Linus Walleij

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

* Re: [PATCH 5/9] gpio: vf610: Extend with wakeup support
@ 2014-09-24  9:19     ` Linus Walleij
  0 siblings, 0 replies; 52+ messages in thread
From: Linus Walleij @ 2014-09-24  9:19 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Shawn Guo, Sascha Hauer, Alexandre Courbot,
	Russell King - ARM Linux, jingchang.lu, Huang Yongcai-B20788,
	linux-arm-kernel, linux-kernel, linux-gpio

On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:

> Support Vybrid GPIO's as wakeup source by requesting the parent
> IRQ as wakeup IRQ.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++

This driver is not yet upstream. Make wakeup support part
of the initial driver submission instead, it doesn't hurt.

Yours,
Linus Walleij

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

* [PATCH 5/9] gpio: vf610: Extend with wakeup support
@ 2014-09-24  9:19     ` Linus Walleij
  0 siblings, 0 replies; 52+ messages in thread
From: Linus Walleij @ 2014-09-24  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:

> Support Vybrid GPIO's as wakeup source by requesting the parent
> IRQ as wakeup IRQ.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++

This driver is not yet upstream. Make wakeup support part
of the initial driver submission instead, it doesn't hurt.

Yours,
Linus Walleij

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

* Re: [PATCH 5/9] gpio: vf610: Extend with wakeup support
  2014-09-22 17:09   ` Stefan Agner
@ 2014-09-24 10:06     ` Lucas Stach
  -1 siblings, 0 replies; 52+ messages in thread
From: Lucas Stach @ 2014-09-24 10:06 UTC (permalink / raw)
  To: Stefan Agner
  Cc: shawn.guo, kernel, linus.walleij, gnurou, linux, jingchang.lu,
	b20788, linux-arm-kernel, linux-kernel, linux-gpio

Hi Stefan,

Am Montag, den 22.09.2014, 19:09 +0200 schrieb Stefan Agner:
> Support Vybrid GPIO's as wakeup source by requesting the parent
> IRQ as wakeup IRQ.
> 
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
> index 5f59424..50326af 100644
> --- a/drivers/gpio/gpio-vf610.c
> +++ b/drivers/gpio/gpio-vf610.c
> @@ -196,12 +196,28 @@ static void vf610_gpio_irq_unmask(struct irq_data *d)
>  			  pcr_base);
>  }
>  
> +static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable)
> +{
> +	struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d);
> +
> +	if (enable)
> +		enable_irq_wake(port->irq);
> +	else
> +		disable_irq_wake(port->irq);
> +
> +	return 0;
> +}
> +
> +
>  static struct irq_chip vf610_gpio_irq_chip = {
>  	.name		= "gpio-vf610",
>  	.irq_ack	= vf610_gpio_irq_ack,
>  	.irq_mask	= vf610_gpio_irq_mask,
>  	.irq_unmask	= vf610_gpio_irq_unmask,
>  	.irq_set_type	= vf610_gpio_irq_set_type,
> +#ifdef CONFIG_PM_SLEEP
> +	.irq_set_wake	= vf610_gpio_irq_set_wake,
> +#endif

Either you need to get rid of this #ifdef and always assign this
function or you need to wrap the function itself into the same #ifdef.
Otherwise you provoke a unused function warning with !CONFIG_PM_SLEEP.

Given that this function isn't really that big I would argue to just
drop the #ifdef.

Regards,
Lucas 

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |


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

* [PATCH 5/9] gpio: vf610: Extend with wakeup support
@ 2014-09-24 10:06     ` Lucas Stach
  0 siblings, 0 replies; 52+ messages in thread
From: Lucas Stach @ 2014-09-24 10:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stefan,

Am Montag, den 22.09.2014, 19:09 +0200 schrieb Stefan Agner:
> Support Vybrid GPIO's as wakeup source by requesting the parent
> IRQ as wakeup IRQ.
> 
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
> index 5f59424..50326af 100644
> --- a/drivers/gpio/gpio-vf610.c
> +++ b/drivers/gpio/gpio-vf610.c
> @@ -196,12 +196,28 @@ static void vf610_gpio_irq_unmask(struct irq_data *d)
>  			  pcr_base);
>  }
>  
> +static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable)
> +{
> +	struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d);
> +
> +	if (enable)
> +		enable_irq_wake(port->irq);
> +	else
> +		disable_irq_wake(port->irq);
> +
> +	return 0;
> +}
> +
> +
>  static struct irq_chip vf610_gpio_irq_chip = {
>  	.name		= "gpio-vf610",
>  	.irq_ack	= vf610_gpio_irq_ack,
>  	.irq_mask	= vf610_gpio_irq_mask,
>  	.irq_unmask	= vf610_gpio_irq_unmask,
>  	.irq_set_type	= vf610_gpio_irq_set_type,
> +#ifdef CONFIG_PM_SLEEP
> +	.irq_set_wake	= vf610_gpio_irq_set_wake,
> +#endif

Either you need to get rid of this #ifdef and always assign this
function or you need to wrap the function itself into the same #ifdef.
Otherwise you provoke a unused function warning with !CONFIG_PM_SLEEP.

Given that this function isn't really that big I would argue to just
drop the #ifdef.

Regards,
Lucas 

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |

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

* [PATCH 0/9] ARM: vf610: Suspend/resume support
  2014-09-24  8:22   ` Stefan Agner
@ 2014-09-24 16:33     ` Bill Pringlemeir
  2014-09-28  3:08       ` Shawn Guo
  0 siblings, 1 reply; 52+ messages in thread
From: Bill Pringlemeir @ 2014-09-24 16:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 24 Sep 2014, stefan at agner.ch wrote:

> Am 2014-09-23 17:36, schrieb Bill Pringlemeir:
>> On 22 Sep 2014, stefan at agner.ch wrote:

[snip]

>>> Power measurement (Colibri VF61, whole module):
>>> - Idle: 540mW
>>> - LP-RUN: 220mW (standby)
>>> - STOP: 200mW (mem)
>>
>>> Stefan Agner (9):
>>> ARM: dts: vf610: Add system reset controller (SRC)
>>> ARM: dts: vf610: add global power controller (GPC)
>>> ARM: dts: vf610: add on-chip SRAM
>>
>> These above three change sets have some implications for dual-chip
>> (Cortex-A5/Cortex-M4) configurations.  Epecially those running MQX.
>> There is not harm to define the register space (except DT size).
>> However, if you activate drivers that manipulate the registers for
>> all systems, then there is no choice to have MQX work on the 2nd
>> core.

> On the Timesys BSP, the kernel is fiddling around with this registers
> too, and AFAIK MQX is working with that kernel. Is MQX really using
> the GPC and SRC modules? I thought MQX is just relying on Linux taking
> care of that.

> Also, you have this problem with other registers as well, for instance
> the CCM module. In fact, to get into deeper sleep modes, you need to
> access the GPC (global power controller) as well as the CCM (clock
> controller module, for instance the CCM_CLPCR register). When you look
> at all the entry sequences, they all fiddling around with the GPC and
> the CCM. And I don't think that the kernel can work properly without
> having control over the clock module.

> IMHO, the SRC and GPC are like the CCM, and need to be under control
> of Linux exclusively.

Yes, it is difficult to see the existing Linux infrastructure working
without these.  The two cores both depend on the same clocks.  You must
use 'clk_ignore_unused' if you want to run both.

> Another case is the SRAM. There are other peripherals which are much
> more important, e.g. both instances of the EDMA modules are currently
> unconditional part of the device tree.

The SRAM is even more of an issue.  Often the MQX is running from the
SRAM.  I agree that the EDMA are actually a bit of an issue as well.
You need to modify MQX to not use them.  However, the MQX use of EDMA
seems stupid, so I prefer Linux to have this feature.  I didn't see
the edma patches when they went in and/or I didn't think of this until I
actually encounter the 'emda' conflict issue.

> Besides, afaik you can also use status = "disabled" in a device tree
> including the vf610.dtsi. The device tree is parsed sequential, the
> last settings wins.

This is true, but in some cases the code is depending on the device
being enabled?  Also, we have automatically compiled in the drivers if
'SOC_VF610' is active.  Ie, there is no way to exclude the code.  The
device tree also becomes a little heavier instead of including them in
the machine file.

>> I think that Shawn Guo already did a patchset to remove stuff from
>> the vf610.dtsi to the machine/configuration DT files.

In this patchset, I suggested that we could include the notation in the
headers which are included in the 'DT' files.  So instead of 'dtsi', we
could use,

   #define VF610_GPC_SUPPORT \
           gpc: gpc at 4006c000 {                \
                   compatible = "fsl,vf610-gpc"; \
                   reg = <0x4006c000 0x1000>;    \
           };

Or even,

   #define VF610_SUSPEND_DT_SUPPORT \ ...

Anyways, the DT issue doesn't matter so much.  People will have to make
custom versions for their own boards.  Although, I don't think it is not
that hard to support it at the machine level.

I agree that so far there are some peripherals that make it difficult to
run the mainline Linux with an MQX.  However, I think this patch set
seems to bring it closer to making it impossible.  I am only suggesting
that we make it a configuration option and not include it for all Vybrid
devices.

Is it clear that the desired way is to use,

   &gpc { status = "disabled"; };
   &src { status = "disabled"; };

We have,

arch/arm/mach-imx/gpc.c

      void __init vf610_gpc_init(void)
      {
              struct device_node *np;

              np = of_find_compatible_node(NULL, NULL, "fsl,vf610-gpc");
              gpc_base = of_iomap(np, 0);
              gpc_imr_base = gpc_base + VF610_GPC_IMR1;
   ...

arch/arm/mach-imx/mach-vf610.c

   static void __init vf610_init_irq(void)
   {
           vf610_gpc_init();
           irqchip_init();
   }

   ...

   +	.init_irq	= vf610_init_irq,

I don't think this will work.  Not to mention that 'mach-vf610.c' will
not build if HAVE_IMX_GPC is not defined.  Also, I don't really see a
use of the GPC module unless suspend/resume is active?   Even some wall
powered designs may wish to exclude this functionality?

I think that the SRC maybe needed for secure parts.  I think that some
designs might wish to restrict Linux's access to these registers as
well.  I don't actually see why we need this module?  I think the imx6
needs it due to multi-CPU bring-up, but in the Vybrid case, this does
not exist.  Can you check to see why we need the SRC?  I don't see where
we actually use it?  In patch9/9, we record it but do we actually access
the registers?  Is it just for the vf610_src_init() code?  Even that
seems the whole 'src.c' file is only needed for the 'src_base'
reference, which we don't use?

Thanks,
Bill Pringlemeir.

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

* Re: [PATCH 5/9] gpio: vf610: Extend with wakeup support
  2014-09-24  9:19     ` Linus Walleij
@ 2014-09-24 16:33       ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-24 16:33 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alexandre Courbot, Russell King - ARM Linux, linux-kernel,
	linux-gpio, linux-arm-kernel, Sascha Hauer, jingchang.lu,
	Huang Yongcai-B20788, Shawn Guo

Am 2014-09-24 11:19, schrieb Linus Walleij:
> On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:
> 
>> Support Vybrid GPIO's as wakeup source by requesting the parent
>> IRQ as wakeup IRQ.
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>> ---
>>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++
> 
> This driver is not yet upstream. Make wakeup support part
> of the initial driver submission instead, it doesn't hurt.

Ok, will do. 

Just realized that this patch even leads to compile errors when applying
on top of v2 of the GPIO driver; we need the irq in drivers struct here,
and I removed that in v2...  :-)

--
Stefan

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

* [PATCH 5/9] gpio: vf610: Extend with wakeup support
@ 2014-09-24 16:33       ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-24 16:33 UTC (permalink / raw)
  To: linux-arm-kernel

Am 2014-09-24 11:19, schrieb Linus Walleij:
> On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:
> 
>> Support Vybrid GPIO's as wakeup source by requesting the parent
>> IRQ as wakeup IRQ.
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>> ---
>>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++
> 
> This driver is not yet upstream. Make wakeup support part
> of the initial driver submission instead, it doesn't hurt.

Ok, will do. 

Just realized that this patch even leads to compile errors when applying
on top of v2 of the GPIO driver; we need the irq in drivers struct here,
and I removed that in v2...  :-)

--
Stefan

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

* Re: [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
  2014-09-24  9:16     ` Linus Walleij
@ 2014-09-24 16:41       ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-24 16:41 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Shawn Guo, Sascha Hauer, Alexandre Courbot,
	Russell King - ARM Linux, jingchang.lu, Huang Yongcai-B20788,
	linux-arm-kernel, linux-kernel, linux-gpio

Am 2014-09-24 11:16, schrieb Linus Walleij:
> On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:
> 
>> Add device tree property for system reset controller.
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
> 
> Are there already device tree bindings for SRC and GRC?

Yes there are used in the i.MX6 world for instance, see imx6qdl.dtsi.
The SRC also has quite generic documentation, however, the GPC module
currently lacks documentation...

--
Stefan


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

* [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
@ 2014-09-24 16:41       ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-24 16:41 UTC (permalink / raw)
  To: linux-arm-kernel

Am 2014-09-24 11:16, schrieb Linus Walleij:
> On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:
> 
>> Add device tree property for system reset controller.
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
> 
> Are there already device tree bindings for SRC and GRC?

Yes there are used in the i.MX6 world for instance, see imx6qdl.dtsi.
The SRC also has quite generic documentation, however, the GPC module
currently lacks documentation...

--
Stefan

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

* Re: [PATCH 5/9] gpio: vf610: Extend with wakeup support
  2014-09-24 10:06     ` Lucas Stach
@ 2014-09-24 16:51       ` Stefan Agner
  -1 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-24 16:51 UTC (permalink / raw)
  To: Lucas Stach
  Cc: shawn.guo, kernel, linus.walleij, gnurou, linux, jingchang.lu,
	b20788, linux-arm-kernel, linux-kernel, linux-gpio

Am 2014-09-24 12:06, schrieb Lucas Stach:
> Hi Stefan,
> 
> Am Montag, den 22.09.2014, 19:09 +0200 schrieb Stefan Agner:
>> Support Vybrid GPIO's as wakeup source by requesting the parent
>> IRQ as wakeup IRQ.
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>> ---
>>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++
>>  1 file changed, 16 insertions(+)
>>
>> diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
>> index 5f59424..50326af 100644
>> --- a/drivers/gpio/gpio-vf610.c
>> +++ b/drivers/gpio/gpio-vf610.c
>> @@ -196,12 +196,28 @@ static void vf610_gpio_irq_unmask(struct irq_data *d)
>>  			  pcr_base);
>>  }
>>
>> +static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable)
>> +{
>> +	struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d);
>> +
>> +	if (enable)
>> +		enable_irq_wake(port->irq);
>> +	else
>> +		disable_irq_wake(port->irq);
>> +
>> +	return 0;
>> +}
>> +
>> +
>>  static struct irq_chip vf610_gpio_irq_chip = {
>>  	.name		= "gpio-vf610",
>>  	.irq_ack	= vf610_gpio_irq_ack,
>>  	.irq_mask	= vf610_gpio_irq_mask,
>>  	.irq_unmask	= vf610_gpio_irq_unmask,
>>  	.irq_set_type	= vf610_gpio_irq_set_type,
>> +#ifdef CONFIG_PM_SLEEP
>> +	.irq_set_wake	= vf610_gpio_irq_set_wake,
>> +#endif
> 
> Either you need to get rid of this #ifdef and always assign this
> function or you need to wrap the function itself into the same #ifdef.
> Otherwise you provoke a unused function warning with !CONFIG_PM_SLEEP.
> 
> Given that this function isn't really that big I would argue to just
> drop the #ifdef.
> 

Good point, thx! I will drop the #ifdef when including that patch to the
GPIO driver (as Linus Walleij suggested).

--
Stefan

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

* [PATCH 5/9] gpio: vf610: Extend with wakeup support
@ 2014-09-24 16:51       ` Stefan Agner
  0 siblings, 0 replies; 52+ messages in thread
From: Stefan Agner @ 2014-09-24 16:51 UTC (permalink / raw)
  To: linux-arm-kernel

Am 2014-09-24 12:06, schrieb Lucas Stach:
> Hi Stefan,
> 
> Am Montag, den 22.09.2014, 19:09 +0200 schrieb Stefan Agner:
>> Support Vybrid GPIO's as wakeup source by requesting the parent
>> IRQ as wakeup IRQ.
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>> ---
>>  drivers/gpio/gpio-vf610.c | 16 ++++++++++++++++
>>  1 file changed, 16 insertions(+)
>>
>> diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
>> index 5f59424..50326af 100644
>> --- a/drivers/gpio/gpio-vf610.c
>> +++ b/drivers/gpio/gpio-vf610.c
>> @@ -196,12 +196,28 @@ static void vf610_gpio_irq_unmask(struct irq_data *d)
>>  			  pcr_base);
>>  }
>>
>> +static int vf610_gpio_irq_set_wake(struct irq_data *d, u32 enable)
>> +{
>> +	struct vf610_gpio_port *port = irq_data_get_irq_chip_data(d);
>> +
>> +	if (enable)
>> +		enable_irq_wake(port->irq);
>> +	else
>> +		disable_irq_wake(port->irq);
>> +
>> +	return 0;
>> +}
>> +
>> +
>>  static struct irq_chip vf610_gpio_irq_chip = {
>>  	.name		= "gpio-vf610",
>>  	.irq_ack	= vf610_gpio_irq_ack,
>>  	.irq_mask	= vf610_gpio_irq_mask,
>>  	.irq_unmask	= vf610_gpio_irq_unmask,
>>  	.irq_set_type	= vf610_gpio_irq_set_type,
>> +#ifdef CONFIG_PM_SLEEP
>> +	.irq_set_wake	= vf610_gpio_irq_set_wake,
>> +#endif
> 
> Either you need to get rid of this #ifdef and always assign this
> function or you need to wrap the function itself into the same #ifdef.
> Otherwise you provoke a unused function warning with !CONFIG_PM_SLEEP.
> 
> Given that this function isn't really that big I would argue to just
> drop the #ifdef.
> 

Good point, thx! I will drop the #ifdef when including that patch to the
GPIO driver (as Linus Walleij suggested).

--
Stefan

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

* Re: [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
  2014-09-24 16:41       ` Stefan Agner
@ 2014-09-25 13:08         ` Philipp Zabel
  -1 siblings, 0 replies; 52+ messages in thread
From: Philipp Zabel @ 2014-09-25 13:08 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Linus Walleij, Shawn Guo, Sascha Hauer, Alexandre Courbot,
	Russell King - ARM Linux, jingchang.lu, Huang Yongcai-B20788,
	linux-arm-kernel, linux-kernel, linux-gpio

Hi Stefan,

Am Mittwoch, den 24.09.2014, 18:41 +0200 schrieb Stefan Agner:
> Am 2014-09-24 11:16, schrieb Linus Walleij:
> > On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:
> > 
> >> Add device tree property for system reset controller.
> >>
> >> Signed-off-by: Stefan Agner <stefan@agner.ch>
> > 
> > Are there already device tree bindings for SRC and GRC?
> 
> Yes there are used in the i.MX6 world for instance, see imx6qdl.dtsi.
> The SRC also has quite generic documentation, however, the GPC module
> currently lacks documentation...

A patch that adds GPC binding documentation is part of this i.MX6 power
domain series:

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

regards
Philipp

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

* [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC)
@ 2014-09-25 13:08         ` Philipp Zabel
  0 siblings, 0 replies; 52+ messages in thread
From: Philipp Zabel @ 2014-09-25 13:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stefan,

Am Mittwoch, den 24.09.2014, 18:41 +0200 schrieb Stefan Agner:
> Am 2014-09-24 11:16, schrieb Linus Walleij:
> > On Mon, Sep 22, 2014 at 7:09 PM, Stefan Agner <stefan@agner.ch> wrote:
> > 
> >> Add device tree property for system reset controller.
> >>
> >> Signed-off-by: Stefan Agner <stefan@agner.ch>
> > 
> > Are there already device tree bindings for SRC and GRC?
> 
> Yes there are used in the i.MX6 world for instance, see imx6qdl.dtsi.
> The SRC also has quite generic documentation, however, the GPC module
> currently lacks documentation...

A patch that adds GPC binding documentation is part of this i.MX6 power
domain series:

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

regards
Philipp

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

* Re: [PATCH 8/9] ARM: imx: clk-gate2: allow custom gate configuration
  2014-09-22 17:09   ` Stefan Agner
  (?)
@ 2014-09-28  2:02     ` Shawn Guo
  -1 siblings, 0 replies; 52+ messages in thread
From: Shawn Guo @ 2014-09-28  2:02 UTC (permalink / raw)
  To: Stefan Agner
  Cc: kernel, linus.walleij, gnurou, linux, jingchang.lu, b20788,
	linux-arm-kernel, linux-kernel, linux-gpio

On Mon, Sep 22, 2014 at 07:09:29PM +0200, Stefan Agner wrote:
> The 2-bit gates found i.MX and Vybrid SoC support different clock
> configuration:
> 
> 0b00: clk disabled
> 0b01: clk enabled in RUN mode but disabled in WAIT and STOP mode
> 0b10: clk enabled in RUN, WAIT and STOP mode (only Vybrid)
> 0b11: clk enabled in RUN and WAIT mode
> 
> For some clocks, we might want to configure different behaviour,
> e.g. a memory clock should be on even in STOP mode. Add a new
> function imx_clk_gate2_cgr which allow to configure specific
> gate values through the cgr_val parameter.
> 
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  arch/arm/mach-imx/clk-gate2.c           |  7 +++++--
>  arch/arm/mach-imx/clk-vf610.c           |  3 +++
>  arch/arm/mach-imx/clk.h                 | 13 ++++++++++---
>  include/dt-bindings/clock/vf610-clock.h |  3 ++-

The patch should be split into two, one for clk-gate2 and the other for
clk-vf610 driver change.  Other than that, the patch looks good to me.

Shawn

>  4 files changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
> index 84acdfd..8c22a84 100644
> --- a/arch/arm/mach-imx/clk-gate2.c
> +++ b/arch/arm/mach-imx/clk-gate2.c
> @@ -31,6 +31,7 @@ struct clk_gate2 {
>  	struct clk_hw hw;
>  	void __iomem	*reg;
>  	u8		bit_idx;
> +	u8		cgr_val;
>  	u8		flags;
>  	spinlock_t	*lock;
>  	unsigned int	*share_count;
> @@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw)
>  		goto out;
>  
>  	reg = readl(gate->reg);
> -	reg |= 3 << gate->bit_idx;
> +	reg &= ~(3 << gate->bit_idx);
> +	reg |= gate->cgr_val << gate->bit_idx;
>  	writel(reg, gate->reg);
>  
>  out:
> @@ -110,7 +112,7 @@ static struct clk_ops clk_gate2_ops = {
>  
>  struct clk *clk_register_gate2(struct device *dev, const char *name,
>  		const char *parent_name, unsigned long flags,
> -		void __iomem *reg, u8 bit_idx,
> +		void __iomem *reg, u8 bit_idx, u8 cgr_val,
>  		u8 clk_gate2_flags, spinlock_t *lock,
>  		unsigned int *share_count)
>  {
> @@ -125,6 +127,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
>  	/* struct clk_gate2 assignments */
>  	gate->reg = reg;
>  	gate->bit_idx = bit_idx;
> +	gate->cgr_val = cgr_val;
>  	gate->flags = clk_gate2_flags;
>  	gate->lock = lock;
>  
> diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
> index a178184..1034e78 100644
> --- a/arch/arm/mach-imx/clk-vf610.c
> +++ b/arch/arm/mach-imx/clk-vf610.c
> @@ -103,6 +103,7 @@ static struct clk_onecell_data clk_data;
>  static unsigned int const clks_init_on[] __initconst = {
>  	VF610_CLK_SYS_BUS,
>  	VF610_CLK_DDR_SEL,
> +	VF610_CLK_DDRMC,
>  };
>  
>  static void __init vf610_clocks_init(struct device_node *ccm_node)
> @@ -171,6 +172,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
>  	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_main_div", "pll4_main", 0, CCM_CACRR, 6, 3, 0, pll4_main_div_table, &imx_ccm_lock);
>  	clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_main_div", "pll6_main", CCM_CACRR, 21, 1);
>  
> +	clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
> +
>  	clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_main", PLL3_CTRL, 6);
>  	clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_main", PLL7_CTRL, 6);
>  
> diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
> index 4cdf8b6..d22e339 100644
> --- a/arch/arm/mach-imx/clk.h
> +++ b/arch/arm/mach-imx/clk.h
> @@ -29,7 +29,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
>  
>  struct clk *clk_register_gate2(struct device *dev, const char *name,
>  		const char *parent_name, unsigned long flags,
> -		void __iomem *reg, u8 bit_idx,
> +		void __iomem *reg, u8 bit_idx, u8 cgr_val,
>  		u8 clk_gate_flags, spinlock_t *lock,
>  		unsigned int *share_count);
>  
> @@ -43,7 +43,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
>  		void __iomem *reg, u8 shift)
>  {
>  	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> -			shift, 0, &imx_ccm_lock, NULL);
> +			shift, 0x3, 0, &imx_ccm_lock, NULL);
>  }
>  
>  static inline struct clk *imx_clk_gate2_shared(const char *name,
> @@ -51,7 +51,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
>  		unsigned int *share_count)
>  {
>  	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> -			shift, 0, &imx_ccm_lock, share_count);
> +			shift, 0x3, 0, &imx_ccm_lock, share_count);
> +}
> +
> +static inline struct clk *imx_clk_gate2_cgr(const char *name,
> +		const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
> +{
> +	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> +			shift, cgr_val, 0, &imx_ccm_lock, NULL);
>  }
>  
>  struct clk *imx_clk_pfd(const char *name, const char *parent_name,
> diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
> index d6b56b2..84c4809 100644
> --- a/include/dt-bindings/clock/vf610-clock.h
> +++ b/include/dt-bindings/clock/vf610-clock.h
> @@ -169,6 +169,7 @@
>  #define VF610_CLK_PLL7_MAIN		156
>  #define VF610_CLK_USBPHY0		157
>  #define VF610_CLK_USBPHY1		158
> -#define VF610_CLK_END			159
> +#define VF610_CLK_DDRMC			159
> +#define VF610_CLK_END			160
>  
>  #endif /* __DT_BINDINGS_CLOCK_VF610_H */
> -- 
> 2.1.0
> 

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

* Re: [PATCH 8/9] ARM: imx: clk-gate2: allow custom gate configuration
@ 2014-09-28  2:02     ` Shawn Guo
  0 siblings, 0 replies; 52+ messages in thread
From: Shawn Guo @ 2014-09-28  2:02 UTC (permalink / raw)
  To: Stefan Agner
  Cc: kernel, linus.walleij, gnurou, linux, jingchang.lu, b20788,
	linux-arm-kernel, linux-kernel, linux-gpio

On Mon, Sep 22, 2014 at 07:09:29PM +0200, Stefan Agner wrote:
> The 2-bit gates found i.MX and Vybrid SoC support different clock
> configuration:
> 
> 0b00: clk disabled
> 0b01: clk enabled in RUN mode but disabled in WAIT and STOP mode
> 0b10: clk enabled in RUN, WAIT and STOP mode (only Vybrid)
> 0b11: clk enabled in RUN and WAIT mode
> 
> For some clocks, we might want to configure different behaviour,
> e.g. a memory clock should be on even in STOP mode. Add a new
> function imx_clk_gate2_cgr which allow to configure specific
> gate values through the cgr_val parameter.
> 
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  arch/arm/mach-imx/clk-gate2.c           |  7 +++++--
>  arch/arm/mach-imx/clk-vf610.c           |  3 +++
>  arch/arm/mach-imx/clk.h                 | 13 ++++++++++---
>  include/dt-bindings/clock/vf610-clock.h |  3 ++-

The patch should be split into two, one for clk-gate2 and the other for
clk-vf610 driver change.  Other than that, the patch looks good to me.

Shawn

>  4 files changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
> index 84acdfd..8c22a84 100644
> --- a/arch/arm/mach-imx/clk-gate2.c
> +++ b/arch/arm/mach-imx/clk-gate2.c
> @@ -31,6 +31,7 @@ struct clk_gate2 {
>  	struct clk_hw hw;
>  	void __iomem	*reg;
>  	u8		bit_idx;
> +	u8		cgr_val;
>  	u8		flags;
>  	spinlock_t	*lock;
>  	unsigned int	*share_count;
> @@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw)
>  		goto out;
>  
>  	reg = readl(gate->reg);
> -	reg |= 3 << gate->bit_idx;
> +	reg &= ~(3 << gate->bit_idx);
> +	reg |= gate->cgr_val << gate->bit_idx;
>  	writel(reg, gate->reg);
>  
>  out:
> @@ -110,7 +112,7 @@ static struct clk_ops clk_gate2_ops = {
>  
>  struct clk *clk_register_gate2(struct device *dev, const char *name,
>  		const char *parent_name, unsigned long flags,
> -		void __iomem *reg, u8 bit_idx,
> +		void __iomem *reg, u8 bit_idx, u8 cgr_val,
>  		u8 clk_gate2_flags, spinlock_t *lock,
>  		unsigned int *share_count)
>  {
> @@ -125,6 +127,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
>  	/* struct clk_gate2 assignments */
>  	gate->reg = reg;
>  	gate->bit_idx = bit_idx;
> +	gate->cgr_val = cgr_val;
>  	gate->flags = clk_gate2_flags;
>  	gate->lock = lock;
>  
> diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
> index a178184..1034e78 100644
> --- a/arch/arm/mach-imx/clk-vf610.c
> +++ b/arch/arm/mach-imx/clk-vf610.c
> @@ -103,6 +103,7 @@ static struct clk_onecell_data clk_data;
>  static unsigned int const clks_init_on[] __initconst = {
>  	VF610_CLK_SYS_BUS,
>  	VF610_CLK_DDR_SEL,
> +	VF610_CLK_DDRMC,
>  };
>  
>  static void __init vf610_clocks_init(struct device_node *ccm_node)
> @@ -171,6 +172,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
>  	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_main_div", "pll4_main", 0, CCM_CACRR, 6, 3, 0, pll4_main_div_table, &imx_ccm_lock);
>  	clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_main_div", "pll6_main", CCM_CACRR, 21, 1);
>  
> +	clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
> +
>  	clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_main", PLL3_CTRL, 6);
>  	clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_main", PLL7_CTRL, 6);
>  
> diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
> index 4cdf8b6..d22e339 100644
> --- a/arch/arm/mach-imx/clk.h
> +++ b/arch/arm/mach-imx/clk.h
> @@ -29,7 +29,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
>  
>  struct clk *clk_register_gate2(struct device *dev, const char *name,
>  		const char *parent_name, unsigned long flags,
> -		void __iomem *reg, u8 bit_idx,
> +		void __iomem *reg, u8 bit_idx, u8 cgr_val,
>  		u8 clk_gate_flags, spinlock_t *lock,
>  		unsigned int *share_count);
>  
> @@ -43,7 +43,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
>  		void __iomem *reg, u8 shift)
>  {
>  	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> -			shift, 0, &imx_ccm_lock, NULL);
> +			shift, 0x3, 0, &imx_ccm_lock, NULL);
>  }
>  
>  static inline struct clk *imx_clk_gate2_shared(const char *name,
> @@ -51,7 +51,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
>  		unsigned int *share_count)
>  {
>  	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> -			shift, 0, &imx_ccm_lock, share_count);
> +			shift, 0x3, 0, &imx_ccm_lock, share_count);
> +}
> +
> +static inline struct clk *imx_clk_gate2_cgr(const char *name,
> +		const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
> +{
> +	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> +			shift, cgr_val, 0, &imx_ccm_lock, NULL);
>  }
>  
>  struct clk *imx_clk_pfd(const char *name, const char *parent_name,
> diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
> index d6b56b2..84c4809 100644
> --- a/include/dt-bindings/clock/vf610-clock.h
> +++ b/include/dt-bindings/clock/vf610-clock.h
> @@ -169,6 +169,7 @@
>  #define VF610_CLK_PLL7_MAIN		156
>  #define VF610_CLK_USBPHY0		157
>  #define VF610_CLK_USBPHY1		158
> -#define VF610_CLK_END			159
> +#define VF610_CLK_DDRMC			159
> +#define VF610_CLK_END			160
>  
>  #endif /* __DT_BINDINGS_CLOCK_VF610_H */
> -- 
> 2.1.0
> 

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

* [PATCH 8/9] ARM: imx: clk-gate2: allow custom gate configuration
@ 2014-09-28  2:02     ` Shawn Guo
  0 siblings, 0 replies; 52+ messages in thread
From: Shawn Guo @ 2014-09-28  2:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 22, 2014 at 07:09:29PM +0200, Stefan Agner wrote:
> The 2-bit gates found i.MX and Vybrid SoC support different clock
> configuration:
> 
> 0b00: clk disabled
> 0b01: clk enabled in RUN mode but disabled in WAIT and STOP mode
> 0b10: clk enabled in RUN, WAIT and STOP mode (only Vybrid)
> 0b11: clk enabled in RUN and WAIT mode
> 
> For some clocks, we might want to configure different behaviour,
> e.g. a memory clock should be on even in STOP mode. Add a new
> function imx_clk_gate2_cgr which allow to configure specific
> gate values through the cgr_val parameter.
> 
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
>  arch/arm/mach-imx/clk-gate2.c           |  7 +++++--
>  arch/arm/mach-imx/clk-vf610.c           |  3 +++
>  arch/arm/mach-imx/clk.h                 | 13 ++++++++++---
>  include/dt-bindings/clock/vf610-clock.h |  3 ++-

The patch should be split into two, one for clk-gate2 and the other for
clk-vf610 driver change.  Other than that, the patch looks good to me.

Shawn

>  4 files changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
> index 84acdfd..8c22a84 100644
> --- a/arch/arm/mach-imx/clk-gate2.c
> +++ b/arch/arm/mach-imx/clk-gate2.c
> @@ -31,6 +31,7 @@ struct clk_gate2 {
>  	struct clk_hw hw;
>  	void __iomem	*reg;
>  	u8		bit_idx;
> +	u8		cgr_val;
>  	u8		flags;
>  	spinlock_t	*lock;
>  	unsigned int	*share_count;
> @@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw)
>  		goto out;
>  
>  	reg = readl(gate->reg);
> -	reg |= 3 << gate->bit_idx;
> +	reg &= ~(3 << gate->bit_idx);
> +	reg |= gate->cgr_val << gate->bit_idx;
>  	writel(reg, gate->reg);
>  
>  out:
> @@ -110,7 +112,7 @@ static struct clk_ops clk_gate2_ops = {
>  
>  struct clk *clk_register_gate2(struct device *dev, const char *name,
>  		const char *parent_name, unsigned long flags,
> -		void __iomem *reg, u8 bit_idx,
> +		void __iomem *reg, u8 bit_idx, u8 cgr_val,
>  		u8 clk_gate2_flags, spinlock_t *lock,
>  		unsigned int *share_count)
>  {
> @@ -125,6 +127,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
>  	/* struct clk_gate2 assignments */
>  	gate->reg = reg;
>  	gate->bit_idx = bit_idx;
> +	gate->cgr_val = cgr_val;
>  	gate->flags = clk_gate2_flags;
>  	gate->lock = lock;
>  
> diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
> index a178184..1034e78 100644
> --- a/arch/arm/mach-imx/clk-vf610.c
> +++ b/arch/arm/mach-imx/clk-vf610.c
> @@ -103,6 +103,7 @@ static struct clk_onecell_data clk_data;
>  static unsigned int const clks_init_on[] __initconst = {
>  	VF610_CLK_SYS_BUS,
>  	VF610_CLK_DDR_SEL,
> +	VF610_CLK_DDRMC,
>  };
>  
>  static void __init vf610_clocks_init(struct device_node *ccm_node)
> @@ -171,6 +172,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
>  	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_main_div", "pll4_main", 0, CCM_CACRR, 6, 3, 0, pll4_main_div_table, &imx_ccm_lock);
>  	clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_main_div", "pll6_main", CCM_CACRR, 21, 1);
>  
> +	clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
> +
>  	clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_main", PLL3_CTRL, 6);
>  	clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_main", PLL7_CTRL, 6);
>  
> diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
> index 4cdf8b6..d22e339 100644
> --- a/arch/arm/mach-imx/clk.h
> +++ b/arch/arm/mach-imx/clk.h
> @@ -29,7 +29,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
>  
>  struct clk *clk_register_gate2(struct device *dev, const char *name,
>  		const char *parent_name, unsigned long flags,
> -		void __iomem *reg, u8 bit_idx,
> +		void __iomem *reg, u8 bit_idx, u8 cgr_val,
>  		u8 clk_gate_flags, spinlock_t *lock,
>  		unsigned int *share_count);
>  
> @@ -43,7 +43,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
>  		void __iomem *reg, u8 shift)
>  {
>  	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> -			shift, 0, &imx_ccm_lock, NULL);
> +			shift, 0x3, 0, &imx_ccm_lock, NULL);
>  }
>  
>  static inline struct clk *imx_clk_gate2_shared(const char *name,
> @@ -51,7 +51,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
>  		unsigned int *share_count)
>  {
>  	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> -			shift, 0, &imx_ccm_lock, share_count);
> +			shift, 0x3, 0, &imx_ccm_lock, share_count);
> +}
> +
> +static inline struct clk *imx_clk_gate2_cgr(const char *name,
> +		const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
> +{
> +	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
> +			shift, cgr_val, 0, &imx_ccm_lock, NULL);
>  }
>  
>  struct clk *imx_clk_pfd(const char *name, const char *parent_name,
> diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
> index d6b56b2..84c4809 100644
> --- a/include/dt-bindings/clock/vf610-clock.h
> +++ b/include/dt-bindings/clock/vf610-clock.h
> @@ -169,6 +169,7 @@
>  #define VF610_CLK_PLL7_MAIN		156
>  #define VF610_CLK_USBPHY0		157
>  #define VF610_CLK_USBPHY1		158
> -#define VF610_CLK_END			159
> +#define VF610_CLK_DDRMC			159
> +#define VF610_CLK_END			160
>  
>  #endif /* __DT_BINDINGS_CLOCK_VF610_H */
> -- 
> 2.1.0
> 

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

* [PATCH 0/9] ARM: vf610: Suspend/resume support
  2014-09-24 16:33     ` Bill Pringlemeir
@ 2014-09-28  3:08       ` Shawn Guo
  2014-09-29 12:47         ` Stefan Agner
  0 siblings, 1 reply; 52+ messages in thread
From: Shawn Guo @ 2014-09-28  3:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 24, 2014 at 12:33:00PM -0400, Bill Pringlemeir wrote:
> >> I think that Shawn Guo already did a patchset to remove stuff from
> >> the vf610.dtsi to the machine/configuration DT files.

Do you mean the pin configuration?  That's really more board-specific.
But IP block/device is not really the case.

> 
> In this patchset, I suggested that we could include the notation in the
> headers which are included in the 'DT' files.  So instead of 'dtsi', we
> could use,
> 
>    #define VF610_GPC_SUPPORT \
>            gpc: gpc at 4006c000 {                \
>                    compatible = "fsl,vf610-gpc"; \
>                    reg = <0x4006c000 0x1000>;    \
>            };
> 
> Or even,
> 
>    #define VF610_SUSPEND_DT_SUPPORT \ ...

I don't think this will be accepted by DT maintainers.  We have already
got some objections when we define pin function ID as multiple integers.
They expect the DT macro is used for single integer case.

> 
> Anyways, the DT issue doesn't matter so much.  People will have to make
> custom versions for their own boards.  Although, I don't think it is not
> that hard to support it at the machine level.
> 
> I agree that so far there are some peripherals that make it difficult to
> run the mainline Linux with an MQX.  However, I think this patch set
> seems to bring it closer to making it impossible.  I am only suggesting
> that we make it a configuration option and not include it for all Vybrid
> devices.
> 
> Is it clear that the desired way is to use,
> 
>    &gpc { status = "disabled"; };
>    &src { status = "disabled"; };
> 
> We have,
> 
> arch/arm/mach-imx/gpc.c
> 
>       void __init vf610_gpc_init(void)
>       {
>               struct device_node *np;
> 
>               np = of_find_compatible_node(NULL, NULL, "fsl,vf610-gpc");
>               gpc_base = of_iomap(np, 0);
>               gpc_imr_base = gpc_base + VF610_GPC_IMR1;
>    ...
> 
> arch/arm/mach-imx/mach-vf610.c
> 
>    static void __init vf610_init_irq(void)
>    {
>            vf610_gpc_init();
>            irqchip_init();
>    }
> 
>    ...
> 
>    +	.init_irq	= vf610_init_irq,
> 
> I don't think this will work.

Yes, you're right.  But I guess this can be fixed by an additional
of_device_is_available() check after of_find_compatible_node() call.

> Not to mention that 'mach-vf610.c' will
> not build if HAVE_IMX_GPC is not defined.

HAVE_IMX_GPC cannot be configured out, because it's selected by 
SOC_VF610.

> Also, I don't really see a
> use of the GPC module unless suspend/resume is active?   Even some wall
> powered designs may wish to exclude this functionality?
> 
> I think that the SRC maybe needed for secure parts.  I think that some
> designs might wish to restrict Linux's access to these registers as
> well.  I don't actually see why we need this module?  I think the imx6
> needs it due to multi-CPU bring-up, but in the Vybrid case, this does
> not exist.  Can you check to see why we need the SRC?  I don't see where
> we actually use it?  In patch9/9, we record it but do we actually access
> the registers?  Is it just for the vf610_src_init() code?  Even that
> seems the whole 'src.c' file is only needed for the 'src_base'
> reference, which we don't use?

+1.  I'm also wondering how SRC is used by suspend routine in this
series.

Shawn

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

* Re: [PATCH 0/9] ARM: vf610: Suspend/resume support
  2014-09-22 17:09 ` Stefan Agner
  (?)
@ 2014-09-28  3:15   ` Shawn Guo
  -1 siblings, 0 replies; 52+ messages in thread
From: Shawn Guo @ 2014-09-28  3:15 UTC (permalink / raw)
  To: Stefan Agner
  Cc: kernel, linus.walleij, gnurou, linux, jingchang.lu, b20788,
	linux-arm-kernel, linux-kernel, linux-gpio

On Mon, Sep 22, 2014 at 07:09:21PM +0200, Stefan Agner wrote:
> This patchset provides suspend/resume support for Freescale Vybrid
> SoC (vf610). The code is generally aligned to the implementation
> for i.MX6. The subsystems SRC and GPC need some changes to support
> the Vybrid specific implementation.
> 
> This patchset relies on GPIO driver to be present (in order to
> provide a wakeup source) as well as using the ARM Global Timer
> clock source (the Vybrid specifc PIT clock source, vf_pit_timer.c
> does not support shutdown).
> 
> The implemented sleep states (LP-RUN and STOP), are not the most
> power saving functions available on Vybrid. Especially for
> suspend-to-memory one of the LPSTOP modes looks more appropriate.
> However, the complexity is somewhat higher (we would need to move
> execution path to SRAM and store IOMUX and DDRMC configuration).
> Currently, I have not the resources to look into that so I hope
> that this initial code qualifies as power saving functions to be
> applied.

So you have quite a lot of unnecessary code which is only needed by
suspend from SRAM (store IOMUX and DDRMC configuration).

Not happy with that.

Shawn

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

* Re: [PATCH 0/9] ARM: vf610: Suspend/resume support
@ 2014-09-28  3:15   ` Shawn Guo
  0 siblings, 0 replies; 52+ messages in thread
From: Shawn Guo @ 2014-09-28  3:15 UTC (permalink / raw)
  To: Stefan Agner
  Cc: kernel, linus.walleij, gnurou, linux, jingchang.lu, b20788,
	linux-arm-kernel, linux-kernel, linux-gpio

On Mon, Sep 22, 2014 at 07:09:21PM +0200, Stefan Agner wrote:
> This patchset provides suspend/resume support for Freescale Vybrid
> SoC (vf610). The code is generally aligned to the implementation
> for i.MX6. The subsystems SRC and GPC need some changes to support
> the Vybrid specific implementation.
> 
> This patchset relies on GPIO driver to be present (in order to
> provide a wakeup source) as well as using the ARM Global Timer
> clock source (the Vybrid specifc PIT clock source, vf_pit_timer.c
> does not support shutdown).
> 
> The implemented sleep states (LP-RUN and STOP), are not the most
> power saving functions available on Vybrid. Especially for
> suspend-to-memory one of the LPSTOP modes looks more appropriate.
> However, the complexity is somewhat higher (we would need to move
> execution path to SRAM and store IOMUX and DDRMC configuration).
> Currently, I have not the resources to look into that so I hope
> that this initial code qualifies as power saving functions to be
> applied.

So you have quite a lot of unnecessary code which is only needed by
suspend from SRAM (store IOMUX and DDRMC configuration).

Not happy with that.

Shawn

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

* [PATCH 0/9] ARM: vf610: Suspend/resume support
@ 2014-09-28  3:15   ` Shawn Guo
  0 siblings, 0 replies; 52+ messages in thread
From: Shawn Guo @ 2014-09-28  3:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 22, 2014 at 07:09:21PM +0200, Stefan Agner wrote:
> This patchset provides suspend/resume support for Freescale Vybrid
> SoC (vf610). The code is generally aligned to the implementation
> for i.MX6. The subsystems SRC and GPC need some changes to support
> the Vybrid specific implementation.
> 
> This patchset relies on GPIO driver to be present (in order to
> provide a wakeup source) as well as using the ARM Global Timer
> clock source (the Vybrid specifc PIT clock source, vf_pit_timer.c
> does not support shutdown).
> 
> The implemented sleep states (LP-RUN and STOP), are not the most
> power saving functions available on Vybrid. Especially for
> suspend-to-memory one of the LPSTOP modes looks more appropriate.
> However, the complexity is somewhat higher (we would need to move
> execution path to SRAM and store IOMUX and DDRMC configuration).
> Currently, I have not the resources to look into that so I hope
> that this initial code qualifies as power saving functions to be
> applied.

So you have quite a lot of unnecessary code which is only needed by
suspend from SRAM (store IOMUX and DDRMC configuration).

Not happy with that.

Shawn

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

* [PATCH 0/9] ARM: vf610: Suspend/resume support
  2014-09-28  3:08       ` Shawn Guo
@ 2014-09-29 12:47         ` Stefan Agner
  2014-09-29 15:39           ` Bill Pringlemeir
  0 siblings, 1 reply; 52+ messages in thread
From: Stefan Agner @ 2014-09-29 12:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bill, Hi Shawn,

Am 2014-09-28 05:08, schrieb Shawn Guo:
> On Wed, Sep 24, 2014 at 12:33:00PM -0400, Bill Pringlemeir wrote:
>> >> I think that Shawn Guo already did a patchset to remove stuff from
>> >> the vf610.dtsi to the machine/configuration DT files.
> 
> Do you mean the pin configuration?  That's really more board-specific.
> But IP block/device is not really the case.
> 
>>
>> In this patchset, I suggested that we could include the notation in the
>> headers which are included in the 'DT' files.  So instead of 'dtsi', we
>> could use,
>>
>>    #define VF610_GPC_SUPPORT \
>>            gpc: gpc at 4006c000 {                \
>>                    compatible = "fsl,vf610-gpc"; \
>>                    reg = <0x4006c000 0x1000>;    \
>>            };
>>
>> Or even,
>>
>>    #define VF610_SUSPEND_DT_SUPPORT \ ...
> 
> I don't think this will be accepted by DT maintainers.  We have already
> got some objections when we define pin function ID as multiple integers.
> They expect the DT macro is used for single integer case.
> 
>>
>> Anyways, the DT issue doesn't matter so much.  People will have to make
>> custom versions for their own boards.  Although, I don't think it is not
>> that hard to support it at the machine level.
>>
>> I agree that so far there are some peripherals that make it difficult to
>> run the mainline Linux with an MQX.  However, I think this patch set
>> seems to bring it closer to making it impossible.  I am only suggesting
>> that we make it a configuration option and not include it for all Vybrid
>> devices.
>>
>> Is it clear that the desired way is to use,
>>
>>    &gpc { status = "disabled"; };
>>    &src { status = "disabled"; };
>>
>> We have,
>>
>> arch/arm/mach-imx/gpc.c
>>
>>       void __init vf610_gpc_init(void)
>>       {
>>               struct device_node *np;
>>
>>               np = of_find_compatible_node(NULL, NULL, "fsl,vf610-gpc");
>>               gpc_base = of_iomap(np, 0);
>>               gpc_imr_base = gpc_base + VF610_GPC_IMR1;
>>    ...
>>
>> arch/arm/mach-imx/mach-vf610.c
>>
>>    static void __init vf610_init_irq(void)
>>    {
>>            vf610_gpc_init();
>>            irqchip_init();
>>    }
>>
>>    ...
>>
>>    +	.init_irq	= vf610_init_irq,
>>
>> I don't think this will work.
> 
> Yes, you're right.  But I guess this can be fixed by an additional
> of_device_is_available() check after of_find_compatible_node() call.
> 
>> Not to mention that 'mach-vf610.c' will
>> not build if HAVE_IMX_GPC is not defined.
> 
> HAVE_IMX_GPC cannot be configured out, because it's selected by 
> SOC_VF610.
> 

Maybe we can make that optional when CONFIG_PM is on, e.g.
select HAVE_IMX_GPC if PM

The GPC module is all about power management, hence in case we want the
M4 taken care of that, we just have to configure a Linux kernel without
CONFIG_PM support.

>> Also, I don't really see a
>> use of the GPC module unless suspend/resume is active?   Even some wall
>> powered designs may wish to exclude this functionality?
>>
>> I think that the SRC maybe needed for secure parts.  I think that some
>> designs might wish to restrict Linux's access to these registers as
>> well.  I don't actually see why we need this module?  I think the imx6
>> needs it due to multi-CPU bring-up, but in the Vybrid case, this does
>> not exist.  Can you check to see why we need the SRC?  I don't see where
>> we actually use it?  In patch9/9, we record it but do we actually access
>> the registers?  Is it just for the vf610_src_init() code?  Even that
>> seems the whole 'src.c' file is only needed for the 'src_base'
>> reference, which we don't use?
> 
> +1.  I'm also wondering how SRC is used by suspend routine in this
> series.

Well I tried to bring LPStop modes to work, which would need GPR0/GPR1
registers of SRC. If I have it working in the next series, I will need
that, but if not, I will drop those changes.

--
Stefan

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

* [PATCH 0/9] ARM: vf610: Suspend/resume support
  2014-09-29 12:47         ` Stefan Agner
@ 2014-09-29 15:39           ` Bill Pringlemeir
  0 siblings, 0 replies; 52+ messages in thread
From: Bill Pringlemeir @ 2014-09-29 15:39 UTC (permalink / raw)
  To: linux-arm-kernel


>> On Wed, Sep 24, 2014 at 12:33:00PM -0400, Bill Pringlemeir wrote:

>>>>> I think that Shawn Guo already did a patchset to remove stuff from
>>>>> the vf610.dtsi to the machine/configuration DT files.

> Am 2014-09-28 05:08, schrieb Shawn Guo:
>> Do you mean the pin configuration?  That's really more
>> board-specific.  But IP block/device is not really the case.

Ok.  But if a DT does not use a IP block/device, then it is extra stuff
in the DT.  I see you only meant the pin configuration which can be
quite large.  So it makes sense to only apply this for the pins.

>> On Wed, Sep 24, 2014 at 12:33:00PM -0400, Bill Pringlemeir wrote:
>>> In this patchset, I suggested that we could include the notation in
>>> the headers which are included in the 'DT' files.  So instead of
>>> 'dtsi', we could use,
>>>
>>> #define VF610_GPC_SUPPORT \
>>> gpc: gpc at 4006c000 {                \
>>> compatible = "fsl,vf610-gpc"; \
>>> reg = <0x4006c000 0x1000>;    \
>>> };
>>>
>>> Or even,
>>>
>>> #define VF610_SUSPEND_DT_SUPPORT \ ...

> Am 2014-09-28 05:08, schrieb Shawn Guo:

>> I don't think this will be accepted by DT maintainers.  We have
>> already got some objections when we define pin function ID as
>> multiple integers.  They expect the DT macro is used for single
>> integer case.

Supporting status="disabled" and/or requiring enabled is also good.  Is
that the 'DT' approved mechanism?

[snip]

>> On Wed, Sep 24, 2014 at 12:33:00PM -0400, Bill Pringlemeir wrote:
>>> We have,
>>>
>>> arch/arm/mach-imx/gpc.c
>>>
>>> void __init vf610_gpc_init(void)
>>> {
>>> struct device_node *np;
>>>
>>> np = of_find_compatible_node(NULL, NULL, "fsl,vf610-gpc");
>>> gpc_base = of_iomap(np, 0);
>>> gpc_imr_base = gpc_base + VF610_GPC_IMR1;
>>> ...
>>>
>>> arch/arm/mach-imx/mach-vf610.c
>>>
>>> static void __init vf610_init_irq(void)
>>> {
>>> vf610_gpc_init();
>>> irqchip_init();
>>> }

>>> I don't think this will work.

> Am 2014-09-28 05:08, schrieb Shawn Guo:

>> Yes, you're right.  But I guess this can be fixed by an additional
>> of_device_is_available() check after of_find_compatible_node() call.

>> On Wed, Sep 24, 2014 at 12:33:00PM -0400, Bill Pringlemeir wrote:

>>> Not to mention that 'mach-vf610.c' will not build if HAVE_IMX_GPC is
>>> not defined.

> Am 2014-09-28 05:08, schrieb Shawn Guo:

>> HAVE_IMX_GPC cannot be configured out, because it's selected by 
>> SOC_VF610.

On 29 Sep 2014, stefan at agner.ch wrote:

> Maybe we can make that optional when CONFIG_PM is on, e.g.
> select HAVE_IMX_GPC if PM

> The GPC module is all about power management, hence in case we want
> the M4 taken care of that, we just have to configure a Linux kernel
> without CONFIG_PM support.

Yes as per the paragraph below, I am concerned about adding too many
modules (or making inter-modules dependencies) in the drivers.  I guess
in a Quad-core iMx6, a system might want one CPU dedicated to some
feature (non-Linux).  For the Vybrid, VF6xx, this is pretty much a sure
thing.  There is an M4, and it does have I/D TCM, but to do anything
useful it has to have some AIPS modules.

>>> Also, I don't really see a use of the GPC module unless
>>> suspend/resume is active?  Even some wall powered designs may wish
>>> to exclude this functionality?

>>> I think that the SRC maybe needed for secure parts.  I think that
>>> some designs might wish to restrict Linux's access to these
>>> registers as well.  I don't actually see why we need this module?  I
>>> think the imx6 needs it due to multi-CPU bring-up, but in the Vybrid
>>> case, this does not exist.  Can you check to see why we need the
>>> SRC?  I don't see where we actually use it?  In patch9/9, we record
>>> it but do we actually access the registers?  Is it just for the
>>> vf610_src_init() code?  Even that seems the whole 'src.c' file is
>>> only needed for the 'src_base' reference, which we don't use?

>> +1.  I'm also wondering how SRC is used by suspend routine in this
>> series.

> Well I tried to bring LPStop modes to work, which would need GPR0/GPR1
> registers of SRC. If I have it working in the next series, I will need
> that, but if not, I will drop those changes.

Most people would want to use at least some IRAM for the M4 code space
as the TCM is rather limited.  Carving off the whole thing for Linux is
not great either.  The imx series had an iram allocator by Sacha Hauer?
However, I don't see this in the mainline anymore.  Is the IRAM
statically allocated by 'DT'?  For the 'memory' node, we keep this in
the machine 'DT', so someone could carve off DDR3 for the M4.  I don't
think the initial series used the IRAM either?  But it is more clear to
me why you wanted that.

I think we might exclude the IRAM and SRC from the initial series?  At
least this patchset might hang around before the LPStop is accepted and
merged? Or you could roll them together so at least we could see what
was next?  I guess you might not have polished the LPSTOP as well and
aren't ready for review.  But I think the changes to remove the SRC and
IRAM aren't too big to get this applied and then later merge them?

Fwiw,
Bill Pringlemeir.

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

end of thread, other threads:[~2014-09-29 15:39 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-22 17:09 [PATCH 0/9] ARM: vf610: Suspend/resume support Stefan Agner
2014-09-22 17:09 ` Stefan Agner
2014-09-22 17:09 ` [PATCH 1/9] ARM: dts: vf610: Add system reset controller (SRC) Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-24  9:16   ` Linus Walleij
2014-09-24  9:16     ` Linus Walleij
2014-09-24  9:16     ` Linus Walleij
2014-09-24 16:41     ` Stefan Agner
2014-09-24 16:41       ` Stefan Agner
2014-09-25 13:08       ` Philipp Zabel
2014-09-25 13:08         ` Philipp Zabel
2014-09-22 17:09 ` [PATCH 2/9] ARM: dts: vf610: add global power controller (GPC) Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09 ` [PATCH 3/9] ARM: dts: vf610: add on-chip SRAM Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09 ` [PATCH 4/9] ARM: dts: vf610-colibri: GPIO power key Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09 ` [PATCH 5/9] gpio: vf610: Extend with wakeup support Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-24  9:19   ` Linus Walleij
2014-09-24  9:19     ` Linus Walleij
2014-09-24  9:19     ` Linus Walleij
2014-09-24 16:33     ` Stefan Agner
2014-09-24 16:33       ` Stefan Agner
2014-09-24 10:06   ` Lucas Stach
2014-09-24 10:06     ` Lucas Stach
2014-09-24 16:51     ` Stefan Agner
2014-09-24 16:51       ` Stefan Agner
2014-09-22 17:09 ` [PATCH 6/9] ARM: imx: gpc: Support vf610 global power controller Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09 ` [PATCH 7/9] ARM: imx: src: Support vf610 system reset controller Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-22 17:09 ` [PATCH 8/9] ARM: imx: clk-gate2: allow custom gate configuration Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-28  2:02   ` Shawn Guo
2014-09-28  2:02     ` Shawn Guo
2014-09-28  2:02     ` Shawn Guo
2014-09-22 17:09 ` [PATCH 9/9] ARM: vf610: initial suspend/resume support Stefan Agner
2014-09-22 17:09   ` Stefan Agner
2014-09-23 15:36 ` [PATCH 0/9] ARM: vf610: Suspend/resume support Bill Pringlemeir
2014-09-24  8:22   ` Stefan Agner
2014-09-24 16:33     ` Bill Pringlemeir
2014-09-28  3:08       ` Shawn Guo
2014-09-29 12:47         ` Stefan Agner
2014-09-29 15:39           ` Bill Pringlemeir
2014-09-28  3:15 ` Shawn Guo
2014-09-28  3:15   ` Shawn Guo
2014-09-28  3:15   ` Shawn Guo

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.