All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x
@ 2014-06-27 13:22 ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Hello,

This patch set adds the CPU Idle support for two mvebu SoCs: the
Armada 370 and the Armada 38x. As there are common parts with the
current support of cpuidle of the Armada XP. I made the code even more
generic. Thanks to this change, adding a new SoC is now only done in
the architecture specific part and we won't have to touch the cpuidle
driver anymore for this.

The first patch is a preliminary clean-up.

The patches 2 and 3 allow to use a common function for the boot
address work around.

The patches 4 and 5 use this function for SMP in the Armada 375 and
CPU idle for the Armada 370.

The patches 6 to 9 and 12 to 13 make the cpu idle support more
generic.

The patches 10 and 11 prepare the cpu idle support for the Armada 38x

The patches 14 and 15 are the ones which really add the cpuidle
support for the Armada 370 and the Armada38x.

And finally the patch 16 updates mvebu_v7_defconfig by selecting the
cpu idle support.

The patches 12 and 13 modify in the same time cpuidle driver and mvebu
code. I need to do this in order to be bisectable. It seems to me that
the easier would be to get the acked-by from the cpuidle maintainer for
this two patches and merged them through the mvebu tree as all the
other patches of the series should also go to the mvebu tree.

Thanks!

Gregory CLEMENT (16):
  ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
  ARM: mvebu: Add a common function for the boot address work around
  ARM: mvebu: Add function to export the physical address of the boot
    register
  ARM: mvebu: Use the common function for Armada 375 SMP workaround
  ARM: mvebu: Add workaround for cpuidle support for Armada 370
  ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
  ARM: mvebu: Make the CPU idle initialization more generic
  ARM: mvebu: Use a local variable to store the resume address
  ARM: mvebu: Make the snoop disable optional in
    mvebu_v7_pmsu_idle_prepare
  ARM: mvebu: Export the SCU address
  ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
  cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
  cpuidle: mvebu: Move the description of the cpuidle states in the
    platform part
  ARM: mvebu: Add CPU idle support for Armada 370
  ARM: mvebu: Add CPU idle support for Armada 38x
  ARM: mvebu: defconfig: Enable CPU Idle support in mvebu_v7_defconfig

 .../bindings/arm/armada-380-mpcore-soc-ctrl.txt    |  14 +
 arch/arm/boot/dts/armada-38x.dtsi                  |   5 +
 arch/arm/configs/mvebu_v7_defconfig                |   2 +
 arch/arm/mach-mvebu/board-v7.c                     |   9 +-
 arch/arm/mach-mvebu/common.h                       |   3 +
 arch/arm/mach-mvebu/headsmp-a9.S                   |  11 -
 arch/arm/mach-mvebu/platsmp-a9.c                   |  27 +-
 arch/arm/mach-mvebu/pmsu.c                         | 312 ++++++++++++++++++---
 arch/arm/mach-mvebu/pmsu.h                         |   1 +
 arch/arm/mach-mvebu/pmsu_ll.S                      |  33 +++
 arch/arm/mach-mvebu/system-controller.c            |  11 +
 drivers/cpuidle/Kconfig.arm                        |   6 +-
 drivers/cpuidle/Makefile                           |   2 +-
 drivers/cpuidle/cpuidle-armada-370-xp.c            |  93 ------
 drivers/cpuidle/cpuidle-mvebu-v7.c                 |  76 +++++
 include/linux/mvebu-v7-cpuidle.h                   |  24 ++
 16 files changed, 456 insertions(+), 173 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
 delete mode 100644 drivers/cpuidle/cpuidle-armada-370-xp.c
 create mode 100644 drivers/cpuidle/cpuidle-mvebu-v7.c
 create mode 100644 include/linux/mvebu-v7-cpuidle.h

-- 
1.8.1.2


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

* [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x
@ 2014-06-27 13:22 ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch set adds the CPU Idle support for two mvebu SoCs: the
Armada 370 and the Armada 38x. As there are common parts with the
current support of cpuidle of the Armada XP. I made the code even more
generic. Thanks to this change, adding a new SoC is now only done in
the architecture specific part and we won't have to touch the cpuidle
driver anymore for this.

The first patch is a preliminary clean-up.

The patches 2 and 3 allow to use a common function for the boot
address work around.

The patches 4 and 5 use this function for SMP in the Armada 375 and
CPU idle for the Armada 370.

The patches 6 to 9 and 12 to 13 make the cpu idle support more
generic.

The patches 10 and 11 prepare the cpu idle support for the Armada 38x

The patches 14 and 15 are the ones which really add the cpuidle
support for the Armada 370 and the Armada38x.

And finally the patch 16 updates mvebu_v7_defconfig by selecting the
cpu idle support.

The patches 12 and 13 modify in the same time cpuidle driver and mvebu
code. I need to do this in order to be bisectable. It seems to me that
the easier would be to get the acked-by from the cpuidle maintainer for
this two patches and merged them through the mvebu tree as all the
other patches of the series should also go to the mvebu tree.

Thanks!

Gregory CLEMENT (16):
  ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
  ARM: mvebu: Add a common function for the boot address work around
  ARM: mvebu: Add function to export the physical address of the boot
    register
  ARM: mvebu: Use the common function for Armada 375 SMP workaround
  ARM: mvebu: Add workaround for cpuidle support for Armada 370
  ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
  ARM: mvebu: Make the CPU idle initialization more generic
  ARM: mvebu: Use a local variable to store the resume address
  ARM: mvebu: Make the snoop disable optional in
    mvebu_v7_pmsu_idle_prepare
  ARM: mvebu: Export the SCU address
  ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
  cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
  cpuidle: mvebu: Move the description of the cpuidle states in the
    platform part
  ARM: mvebu: Add CPU idle support for Armada 370
  ARM: mvebu: Add CPU idle support for Armada 38x
  ARM: mvebu: defconfig: Enable CPU Idle support in mvebu_v7_defconfig

 .../bindings/arm/armada-380-mpcore-soc-ctrl.txt    |  14 +
 arch/arm/boot/dts/armada-38x.dtsi                  |   5 +
 arch/arm/configs/mvebu_v7_defconfig                |   2 +
 arch/arm/mach-mvebu/board-v7.c                     |   9 +-
 arch/arm/mach-mvebu/common.h                       |   3 +
 arch/arm/mach-mvebu/headsmp-a9.S                   |  11 -
 arch/arm/mach-mvebu/platsmp-a9.c                   |  27 +-
 arch/arm/mach-mvebu/pmsu.c                         | 312 ++++++++++++++++++---
 arch/arm/mach-mvebu/pmsu.h                         |   1 +
 arch/arm/mach-mvebu/pmsu_ll.S                      |  33 +++
 arch/arm/mach-mvebu/system-controller.c            |  11 +
 drivers/cpuidle/Kconfig.arm                        |   6 +-
 drivers/cpuidle/Makefile                           |   2 +-
 drivers/cpuidle/cpuidle-armada-370-xp.c            |  93 ------
 drivers/cpuidle/cpuidle-mvebu-v7.c                 |  76 +++++
 include/linux/mvebu-v7-cpuidle.h                   |  24 ++
 16 files changed, 456 insertions(+), 173 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
 delete mode 100644 drivers/cpuidle/cpuidle-armada-370-xp.c
 create mode 100644 drivers/cpuidle/cpuidle-mvebu-v7.c
 create mode 100644 include/linux/mvebu-v7-cpuidle.h

-- 
1.8.1.2

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

* [PATCH 01/16] ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Sorting the headers in alphabetic order will help to reduce the
conflict when adding new headers later.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index a1d407c0febe..5584d35b8e88 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -19,13 +19,13 @@
 #define pr_fmt(fmt) "mvebu-pmsu: " fmt
 
 #include <linux/cpu_pm.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/of_address.h>
+#include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
-#include <linux/smp.h>
 #include <linux/resource.h>
+#include <linux/smp.h>
 #include <asm/cacheflush.h>
 #include <asm/cp15.h>
 #include <asm/smp_plat.h>
-- 
1.8.1.2


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

* [PATCH 01/16] ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

Sorting the headers in alphabetic order will help to reduce the
conflict when adding new headers later.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index a1d407c0febe..5584d35b8e88 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -19,13 +19,13 @@
 #define pr_fmt(fmt) "mvebu-pmsu: " fmt
 
 #include <linux/cpu_pm.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/of_address.h>
+#include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
-#include <linux/smp.h>
 #include <linux/resource.h>
+#include <linux/smp.h>
 #include <asm/cacheflush.h>
 #include <asm/cp15.h>
 #include <asm/smp_plat.h>
-- 
1.8.1.2

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

* [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

On some of the mvebu SoC and due to internal bootrom issue, CPU
initial jump code should be placed in SRAM memory of the SoC. In order
to achieve this, we have to unmap the BootROM and at some specific
location where the BootROM was place, create a specific MBus window
for the SRAM. This SRAM is initialized with a few instructions of code
that allows to jump into the real secondary CPU boot address.

This work around currently needed for booting SMP on Aramda 375 Z1 and
will be needed for cpuidle support on Armada 370. Instead of duplicate
the same code, this commit introduce a common function to handle it:
mvebu_boot_addr_wa().

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c    | 31 +++++++++++++++++++++++++++++++
 arch/arm/mach-mvebu/pmsu.h    |  1 +
 arch/arm/mach-mvebu/pmsu_ll.S | 19 +++++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 5584d35b8e88..991560905ccc 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/mbus.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
@@ -63,6 +64,14 @@ static void __iomem *pmsu_mp_base;
 #define L2C_NFABRIC_PM_CTL		    0x4
 #define L2C_NFABRIC_PM_CTL_PWR_DOWN		BIT(20)
 
+#define ARMADA_370_CRYPT0_ENG_ID	0x9
+#define CRYPT0_ENG_ATTR	0x1
+
+#define SRAM_PHYS_BASE	    0xFFFF0000
+
+#define BOOTROM_BASE    0xFFF00000
+#define BOOTROM_SIZE    0x100000
+
 extern void ll_disable_coherency(void);
 extern void ll_enable_coherency(void);
 
@@ -85,6 +94,28 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
 		PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
 }
 
+extern unsigned char mvebu_boot_wa_start;
+extern unsigned char mvebu_boot_wa_end;
+
+void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
+{
+	void __iomem *sram_virt_base;
+	u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
+
+	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
+	mvebu_mbus_add_window_by_id(crypto_eng_id, CRYPT0_ENG_ATTR,
+				SRAM_PHYS_BASE, SZ_64K);
+	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
+
+
+	memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
+	/*
+	 * The last word of the code copied in SRAM must contain the
+	 * physical base address of the PMSU register
+	 */
+	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
+}
+
 static int __init armada_370_xp_pmsu_init(void)
 {
 	struct device_node *np;
diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h
index 07a737c6b95d..2d97a70c2558 100644
--- a/arch/arm/mach-mvebu/pmsu.h
+++ b/arch/arm/mach-mvebu/pmsu.h
@@ -12,5 +12,6 @@
 #define __MACH_MVEBU_PMSU_H
 
 int armada_xp_boot_cpu(unsigned int cpu_id, void *phys_addr);
+void mvebu_boot_addr_wa(int crypto_eng_id, unsigned long resume_addr_reg);
 
 #endif	/* __MACH_370_XP_PMSU_H */
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index fc3de68d8c54..3b702a16bd3d 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -23,3 +23,22 @@ ARM_BE8(setend	be )			@ go BE8 if entered LE
 	b	cpu_resume
 ENDPROC(armada_370_xp_cpu_resume)
 
+.global mvebu_boot_wa_start
+.global mvebu_boot_wa_end
+
+/* The following code will be executed from SRAM */
+ENTRY(mvebu_boot_wa_start)
+mvebu_boot_wa_start:
+/* use physical address of the boot address register register */
+	adr     r0, 1f
+	ldr     r0, [r0]
+	ldr     r0, [r0]
+	mov     pc, r0
+/*
+ * the last word of this piece of code will be filled by the physical
+ * address of the boot address register just after being copied in SRAM
+ */
+1:
+	.long   .
+mvebu_boot_wa_end:
+ENDPROC(mvebu_boot_wa_end)
-- 
1.8.1.2


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

* [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

On some of the mvebu SoC and due to internal bootrom issue, CPU
initial jump code should be placed in SRAM memory of the SoC. In order
to achieve this, we have to unmap the BootROM and at some specific
location where the BootROM was place, create a specific MBus window
for the SRAM. This SRAM is initialized with a few instructions of code
that allows to jump into the real secondary CPU boot address.

This work around currently needed for booting SMP on Aramda 375 Z1 and
will be needed for cpuidle support on Armada 370. Instead of duplicate
the same code, this commit introduce a common function to handle it:
mvebu_boot_addr_wa().

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c    | 31 +++++++++++++++++++++++++++++++
 arch/arm/mach-mvebu/pmsu.h    |  1 +
 arch/arm/mach-mvebu/pmsu_ll.S | 19 +++++++++++++++++++
 3 files changed, 51 insertions(+)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 5584d35b8e88..991560905ccc 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/mbus.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
@@ -63,6 +64,14 @@ static void __iomem *pmsu_mp_base;
 #define L2C_NFABRIC_PM_CTL		    0x4
 #define L2C_NFABRIC_PM_CTL_PWR_DOWN		BIT(20)
 
+#define ARMADA_370_CRYPT0_ENG_ID	0x9
+#define CRYPT0_ENG_ATTR	0x1
+
+#define SRAM_PHYS_BASE	    0xFFFF0000
+
+#define BOOTROM_BASE    0xFFF00000
+#define BOOTROM_SIZE    0x100000
+
 extern void ll_disable_coherency(void);
 extern void ll_enable_coherency(void);
 
@@ -85,6 +94,28 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
 		PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
 }
 
+extern unsigned char mvebu_boot_wa_start;
+extern unsigned char mvebu_boot_wa_end;
+
+void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
+{
+	void __iomem *sram_virt_base;
+	u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
+
+	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
+	mvebu_mbus_add_window_by_id(crypto_eng_id, CRYPT0_ENG_ATTR,
+				SRAM_PHYS_BASE, SZ_64K);
+	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
+
+
+	memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
+	/*
+	 * The last word of the code copied in SRAM must contain the
+	 * physical base address of the PMSU register
+	 */
+	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
+}
+
 static int __init armada_370_xp_pmsu_init(void)
 {
 	struct device_node *np;
diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h
index 07a737c6b95d..2d97a70c2558 100644
--- a/arch/arm/mach-mvebu/pmsu.h
+++ b/arch/arm/mach-mvebu/pmsu.h
@@ -12,5 +12,6 @@
 #define __MACH_MVEBU_PMSU_H
 
 int armada_xp_boot_cpu(unsigned int cpu_id, void *phys_addr);
+void mvebu_boot_addr_wa(int crypto_eng_id, unsigned long resume_addr_reg);
 
 #endif	/* __MACH_370_XP_PMSU_H */
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index fc3de68d8c54..3b702a16bd3d 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -23,3 +23,22 @@ ARM_BE8(setend	be )			@ go BE8 if entered LE
 	b	cpu_resume
 ENDPROC(armada_370_xp_cpu_resume)
 
+.global mvebu_boot_wa_start
+.global mvebu_boot_wa_end
+
+/* The following code will be executed from SRAM */
+ENTRY(mvebu_boot_wa_start)
+mvebu_boot_wa_start:
+/* use physical address of the boot address register register */
+	adr     r0, 1f
+	ldr     r0, [r0]
+	ldr     r0, [r0]
+	mov     pc, r0
+/*
+ * the last word of this piece of code will be filled by the physical
+ * address of the boot address register just after being copied in SRAM
+ */
+1:
+	.long   .
+mvebu_boot_wa_end:
+ENDPROC(mvebu_boot_wa_end)
-- 
1.8.1.2

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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

In order to boot the secondary CPUs on Armada 375 Z1, we need to read
the boot address of these CPUs through a register part of the System
Controller. This done very early where MMU is not enable yet, so we
need to get the physical address of this register to use it.

In the previous version of this workaround the physical address were
hardcoded whereas depending of the Mbus configuration this address may
change.

This commit will allow to use the generic boot workaround function
with the correct address.
---
 arch/arm/mach-mvebu/common.h            |  1 +
 arch/arm/mach-mvebu/system-controller.c | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index b67fb7a10d8b..6ad62cf8352c 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -20,6 +20,7 @@
 void mvebu_restart(enum reboot_mode mode, const char *cmd);
 int mvebu_cpu_reset_deassert(int cpu);
 void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
+u32 mvebu_system_controller_get_phys_addr(void);
 void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
 
 void armada_xp_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
index 0c5524ac75b7..ae6ab543aa36 100644
--- a/arch/arm/mach-mvebu/system-controller.c
+++ b/arch/arm/mach-mvebu/system-controller.c
@@ -30,6 +30,7 @@
 #include "common.h"
 
 static void __iomem *system_controller_base;
+static u32 system_controller_phys_base;
 
 struct mvebu_system_controller {
 	u32 rstoutn_mask_offset;
@@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
 	writel(virt_to_phys(boot_addr), system_controller_base +
 	       mvebu_sc->resume_boot_addr);
 }
+
+u32 mvebu_system_controller_get_phys_addr(void)
+{
+	BUG_ON(system_controller_phys_base == NULL);
+	BUG_ON(mvebu_sc->resume_boot_addr == 0);
+	return system_controller_phys_base + mvebu_sc->resume_boot_addr;
+}
 #endif
 
 static int __init mvebu_system_controller_init(void)
@@ -119,7 +127,10 @@ static int __init mvebu_system_controller_init(void)
 	np = of_find_matching_node_and_match(NULL, of_system_controller_table,
 					     &match);
 	if (np) {
+		struct resource res;
 		system_controller_base = of_iomap(np, 0);
+		of_address_to_resource(np, 0, &res);
+		system_controller_phys_base = res.start;
 		mvebu_sc = (struct mvebu_system_controller *)match->data;
 		of_node_put(np);
 	}
-- 
1.8.1.2


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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

In order to boot the secondary CPUs on Armada 375 Z1, we need to read
the boot address of these CPUs through a register part of the System
Controller. This done very early where MMU is not enable yet, so we
need to get the physical address of this register to use it.

In the previous version of this workaround the physical address were
hardcoded whereas depending of the Mbus configuration this address may
change.

This commit will allow to use the generic boot workaround function
with the correct address.
---
 arch/arm/mach-mvebu/common.h            |  1 +
 arch/arm/mach-mvebu/system-controller.c | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index b67fb7a10d8b..6ad62cf8352c 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -20,6 +20,7 @@
 void mvebu_restart(enum reboot_mode mode, const char *cmd);
 int mvebu_cpu_reset_deassert(int cpu);
 void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
+u32 mvebu_system_controller_get_phys_addr(void);
 void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
 
 void armada_xp_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
index 0c5524ac75b7..ae6ab543aa36 100644
--- a/arch/arm/mach-mvebu/system-controller.c
+++ b/arch/arm/mach-mvebu/system-controller.c
@@ -30,6 +30,7 @@
 #include "common.h"
 
 static void __iomem *system_controller_base;
+static u32 system_controller_phys_base;
 
 struct mvebu_system_controller {
 	u32 rstoutn_mask_offset;
@@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
 	writel(virt_to_phys(boot_addr), system_controller_base +
 	       mvebu_sc->resume_boot_addr);
 }
+
+u32 mvebu_system_controller_get_phys_addr(void)
+{
+	BUG_ON(system_controller_phys_base == NULL);
+	BUG_ON(mvebu_sc->resume_boot_addr == 0);
+	return system_controller_phys_base + mvebu_sc->resume_boot_addr;
+}
 #endif
 
 static int __init mvebu_system_controller_init(void)
@@ -119,7 +127,10 @@ static int __init mvebu_system_controller_init(void)
 	np = of_find_matching_node_and_match(NULL, of_system_controller_table,
 					     &match);
 	if (np) {
+		struct resource res;
 		system_controller_base = of_iomap(np, 0);
+		of_address_to_resource(np, 0, &res);
+		system_controller_phys_base = res.start;
 		mvebu_sc = (struct mvebu_system_controller *)match->data;
 		of_node_put(np);
 	}
-- 
1.8.1.2

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

* [PATCH 04/16] ARM: mvebu: Use the common function for Armada 375 SMP workaround
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Use the common function mvebu_boot_addr_wa() introduced in the
previous commit instead of the dedicated version for Armada 375.

In bonus we don't use anymore an harcoded value to access the register
storing the boot address.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/headsmp-a9.S | 11 -----------
 arch/arm/mach-mvebu/platsmp-a9.c | 27 +++------------------------
 2 files changed, 3 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S
index 5925366bc03c..e48c8c495975 100644
--- a/arch/arm/mach-mvebu/headsmp-a9.S
+++ b/arch/arm/mach-mvebu/headsmp-a9.S
@@ -16,17 +16,6 @@
 #include <linux/init.h>
 
 	__CPUINIT
-#define CPU_RESUME_ADDR_REG 0xf10182d4
-
-.global armada_375_smp_cpu1_enable_code_start
-.global armada_375_smp_cpu1_enable_code_end
-
-armada_375_smp_cpu1_enable_code_start:
-	ldr     r0, [pc, #4]
-	ldr     r1, [r0]
-	mov     pc, r1
-	.word   CPU_RESUME_ADDR_REG
-armada_375_smp_cpu1_enable_code_end:
 
 ENTRY(mvebu_cortex_a9_secondary_startup)
 	bl      v7_invalidate_l1
diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c
index 96c2c59e34b6..5805c97502e3 100644
--- a/arch/arm/mach-mvebu/platsmp-a9.c
+++ b/arch/arm/mach-mvebu/platsmp-a9.c
@@ -23,29 +23,7 @@
 #include "mvebu-soc-id.h"
 #include "pmsu.h"
 
-#define CRYPT0_ENG_ID   41
-#define CRYPT0_ENG_ATTR 0x1
-#define SRAM_PHYS_BASE  0xFFFF0000
-
-#define BOOTROM_BASE    0xFFF00000
-#define BOOTROM_SIZE    0x100000
-
-extern unsigned char armada_375_smp_cpu1_enable_code_end;
-extern unsigned char armada_375_smp_cpu1_enable_code_start;
-
-void armada_375_smp_cpu1_enable_wa(void)
-{
-	void __iomem *sram_virt_base;
-
-	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
-	mvebu_mbus_add_window_by_id(CRYPT0_ENG_ID, CRYPT0_ENG_ATTR,
-				SRAM_PHYS_BASE, SZ_64K);
-	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
-
-	memcpy(sram_virt_base, &armada_375_smp_cpu1_enable_code_start,
-	       &armada_375_smp_cpu1_enable_code_end
-	       - &armada_375_smp_cpu1_enable_code_start);
-}
+#define ARMADA_375_CRYPT0_ENG_ID   41
 
 extern void mvebu_cortex_a9_secondary_startup(void);
 
@@ -69,7 +47,8 @@ static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu,
 
 		if (mvebu_get_soc_id(&dev, &rev) == 0 &&
 		    rev == ARMADA_375_Z1_REV)
-			armada_375_smp_cpu1_enable_wa();
+				mvebu_boot_addr_wa(ARMADA_375_CRYPT0_ENG_ID,
+					mvebu_system_controller_get_phys_addr());
 
 		mvebu_system_controller_set_cpu_boot_addr(mvebu_cortex_a9_secondary_startup);
 	}
-- 
1.8.1.2


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

* [PATCH 04/16] ARM: mvebu: Use the common function for Armada 375 SMP workaround
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

Use the common function mvebu_boot_addr_wa() introduced in the
previous commit instead of the dedicated version for Armada 375.

In bonus we don't use anymore an harcoded value to access the register
storing the boot address.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/headsmp-a9.S | 11 -----------
 arch/arm/mach-mvebu/platsmp-a9.c | 27 +++------------------------
 2 files changed, 3 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S
index 5925366bc03c..e48c8c495975 100644
--- a/arch/arm/mach-mvebu/headsmp-a9.S
+++ b/arch/arm/mach-mvebu/headsmp-a9.S
@@ -16,17 +16,6 @@
 #include <linux/init.h>
 
 	__CPUINIT
-#define CPU_RESUME_ADDR_REG 0xf10182d4
-
-.global armada_375_smp_cpu1_enable_code_start
-.global armada_375_smp_cpu1_enable_code_end
-
-armada_375_smp_cpu1_enable_code_start:
-	ldr     r0, [pc, #4]
-	ldr     r1, [r0]
-	mov     pc, r1
-	.word   CPU_RESUME_ADDR_REG
-armada_375_smp_cpu1_enable_code_end:
 
 ENTRY(mvebu_cortex_a9_secondary_startup)
 	bl      v7_invalidate_l1
diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c
index 96c2c59e34b6..5805c97502e3 100644
--- a/arch/arm/mach-mvebu/platsmp-a9.c
+++ b/arch/arm/mach-mvebu/platsmp-a9.c
@@ -23,29 +23,7 @@
 #include "mvebu-soc-id.h"
 #include "pmsu.h"
 
-#define CRYPT0_ENG_ID   41
-#define CRYPT0_ENG_ATTR 0x1
-#define SRAM_PHYS_BASE  0xFFFF0000
-
-#define BOOTROM_BASE    0xFFF00000
-#define BOOTROM_SIZE    0x100000
-
-extern unsigned char armada_375_smp_cpu1_enable_code_end;
-extern unsigned char armada_375_smp_cpu1_enable_code_start;
-
-void armada_375_smp_cpu1_enable_wa(void)
-{
-	void __iomem *sram_virt_base;
-
-	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
-	mvebu_mbus_add_window_by_id(CRYPT0_ENG_ID, CRYPT0_ENG_ATTR,
-				SRAM_PHYS_BASE, SZ_64K);
-	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
-
-	memcpy(sram_virt_base, &armada_375_smp_cpu1_enable_code_start,
-	       &armada_375_smp_cpu1_enable_code_end
-	       - &armada_375_smp_cpu1_enable_code_start);
-}
+#define ARMADA_375_CRYPT0_ENG_ID   41
 
 extern void mvebu_cortex_a9_secondary_startup(void);
 
@@ -69,7 +47,8 @@ static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu,
 
 		if (mvebu_get_soc_id(&dev, &rev) == 0 &&
 		    rev == ARMADA_375_Z1_REV)
-			armada_375_smp_cpu1_enable_wa();
+				mvebu_boot_addr_wa(ARMADA_375_CRYPT0_ENG_ID,
+					mvebu_system_controller_get_phys_addr());
 
 		mvebu_system_controller_set_cpu_boot_addr(mvebu_cortex_a9_secondary_startup);
 	}
-- 
1.8.1.2

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

* [PATCH 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

On Armada 370, there is "a slow exit process from the deep idle state
due to heavy L1/L2 cache cleanup operations performed by the BootROM
software" (cf errata GL-BootROM-10). To avoid this, we replace the
restart code of the BootROM by a simple jump to the boot address. Then
the code located at this boot address will take care of the
initialization.

For this purpose, we use the common function mvebu_boot_addr_wa()
introduced in the previous commit.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 991560905ccc..cdc6d87d0b49 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -34,7 +34,6 @@
 #include <asm/tlbflush.h>
 #include "common.h"
 
-static void __iomem *pmsu_mp_base;
 
 #define PMSU_BASE_OFFSET    0x100
 #define PMSU_REG_SIZE	    0x1000
@@ -77,6 +76,9 @@ extern void ll_enable_coherency(void);
 
 extern void armada_370_xp_cpu_resume(void);
 
+static unsigned long pmsu_mp_phys_base;
+static void __iomem *pmsu_mp_base;
+
 static struct platform_device armada_xp_cpuidle_device = {
 	.name = "cpuidle-armada-370-xp",
 };
@@ -147,6 +149,8 @@ static int __init armada_370_xp_pmsu_init(void)
 		goto out;
 	}
 
+	pmsu_mp_phys_base = res.start;
+
 	pmsu_mp_base = ioremap(res.start, resource_size(&res));
 	if (!pmsu_mp_base) {
 		pr_err("unable to map registers\n");
@@ -312,6 +316,18 @@ int __init armada_370_xp_cpu_pm_init(void)
 		return 0;
 	of_node_put(np);
 
+	/*
+	 * On Armada 370, there is "a slow exit process from the deep
+	 * idle state due to heavy L1/L2 cache cleanup operations
+	 * performed by the BootROM software". To avoid this, we
+	 * replace the restart code of the bootrom by a a simple jump
+	 * to the boot address. Then the code located at this boot
+	 * address will take care of the initialization.
+	 */
+	if (of_machine_is_compatible("marvell,armada370"))
+		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
+				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
+
 	armada_370_xp_pmsu_enable_l2_powerdown_onidle();
 	armada_xp_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
 	platform_device_register(&armada_xp_cpuidle_device);
-- 
1.8.1.2


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

* [PATCH 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Armada 370, there is "a slow exit process from the deep idle state
due to heavy L1/L2 cache cleanup operations performed by the BootROM
software" (cf errata GL-BootROM-10). To avoid this, we replace the
restart code of the BootROM by a simple jump to the boot address. Then
the code located at this boot address will take care of the
initialization.

For this purpose, we use the common function mvebu_boot_addr_wa()
introduced in the previous commit.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 991560905ccc..cdc6d87d0b49 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -34,7 +34,6 @@
 #include <asm/tlbflush.h>
 #include "common.h"
 
-static void __iomem *pmsu_mp_base;
 
 #define PMSU_BASE_OFFSET    0x100
 #define PMSU_REG_SIZE	    0x1000
@@ -77,6 +76,9 @@ extern void ll_enable_coherency(void);
 
 extern void armada_370_xp_cpu_resume(void);
 
+static unsigned long pmsu_mp_phys_base;
+static void __iomem *pmsu_mp_base;
+
 static struct platform_device armada_xp_cpuidle_device = {
 	.name = "cpuidle-armada-370-xp",
 };
@@ -147,6 +149,8 @@ static int __init armada_370_xp_pmsu_init(void)
 		goto out;
 	}
 
+	pmsu_mp_phys_base = res.start;
+
 	pmsu_mp_base = ioremap(res.start, resource_size(&res));
 	if (!pmsu_mp_base) {
 		pr_err("unable to map registers\n");
@@ -312,6 +316,18 @@ int __init armada_370_xp_cpu_pm_init(void)
 		return 0;
 	of_node_put(np);
 
+	/*
+	 * On Armada 370, there is "a slow exit process from the deep
+	 * idle state due to heavy L1/L2 cache cleanup operations
+	 * performed by the BootROM software". To avoid this, we
+	 * replace the restart code of the bootrom by a a simple jump
+	 * to the boot address. Then the code located at this boot
+	 * address will take care of the initialization.
+	 */
+	if (of_machine_is_compatible("marvell,armada370"))
+		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
+				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
+
 	armada_370_xp_pmsu_enable_l2_powerdown_onidle();
 	armada_xp_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
 	platform_device_register(&armada_xp_cpuidle_device);
-- 
1.8.1.2

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

* [PATCH 06/16] ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Actually most of the function related to the PMSU are not specific to
the Armada 370 or Armada XP SoCs, but can also be used for most of the
other mvebu ARMv7 SoCs.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index cdc6d87d0b49..087157c20b8a 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -79,7 +79,7 @@ extern void armada_370_xp_cpu_resume(void);
 static unsigned long pmsu_mp_phys_base;
 static void __iomem *pmsu_mp_base;
 
-static struct platform_device armada_xp_cpuidle_device = {
+static struct platform_device mvebu_v7_cpuidle_device = {
 	.name = "cpuidle-armada-370-xp",
 };
 
@@ -118,7 +118,7 @@ void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
 	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
 }
 
-static int __init armada_370_xp_pmsu_init(void)
+static int __init mvebu_v7_pmsu_init(void)
 {
 	struct device_node *np;
 	struct resource res;
@@ -164,7 +164,7 @@ static int __init armada_370_xp_pmsu_init(void)
 	return ret;
 }
 
-static void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void)
+static void mvebu_v7_pmsu_enable_l2_powerdown_onidle(void)
 {
 	u32 reg;
 
@@ -178,7 +178,7 @@ static void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void)
 }
 
 /* No locking is needed because we only access per-CPU registers */
-void armada_370_xp_pmsu_idle_prepare(bool deepidle)
+static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
 {
 	unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
 	u32 reg;
@@ -215,9 +215,9 @@ void armada_370_xp_pmsu_idle_prepare(bool deepidle)
 	writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
 }
 
-static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
+static noinline int do_armada_xp_370_cpu_suspend(unsigned long deepidle)
 {
-	armada_370_xp_pmsu_idle_prepare(deepidle);
+	mvebu_v7_pmsu_idle_prepare(deepidle);
 
 	v7_exit_coherency_flush(all);
 
@@ -248,13 +248,13 @@ static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
 	return 0;
 }
 
-static int armada_370_xp_cpu_suspend(unsigned long deepidle)
+static int armada_xp_370_cpu_suspend(unsigned long deepidle)
 {
-	return cpu_suspend(deepidle, do_armada_370_xp_cpu_suspend);
+	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
 }
 
 /* No locking is needed because we only access per-CPU registers */
-static noinline void armada_370_xp_pmsu_idle_restore(void)
+static noinline void mvebu_v7_pmsu_idle_restore(void)
 {
 	unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
 	u32 reg;
@@ -276,24 +276,24 @@ static noinline void armada_370_xp_pmsu_idle_restore(void)
 	writel(reg, pmsu_mp_base + PMSU_STATUS_AND_MASK(hw_cpu));
 }
 
-static int armada_370_xp_cpu_pm_notify(struct notifier_block *self,
+static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
 				    unsigned long action, void *hcpu)
 {
 	if (action == CPU_PM_ENTER) {
 		unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
 		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
 	} else if (action == CPU_PM_EXIT) {
-		armada_370_xp_pmsu_idle_restore();
+		mvebu_v7_pmsu_idle_restore();
 	}
 
 	return NOTIFY_OK;
 }
 
-static struct notifier_block armada_370_xp_cpu_pm_notifier = {
-	.notifier_call = armada_370_xp_cpu_pm_notify,
+static struct notifier_block mvebu_v7_cpu_pm_notifier = {
+	.notifier_call = mvebu_v7_cpu_pm_notify,
 };
 
-int __init armada_370_xp_cpu_pm_init(void)
+static int __init mvebu_v7_cpu_pm_init(void)
 {
 	struct device_node *np;
 
@@ -328,13 +328,13 @@ int __init armada_370_xp_cpu_pm_init(void)
 		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
 				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
 
-	armada_370_xp_pmsu_enable_l2_powerdown_onidle();
-	armada_xp_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
-	platform_device_register(&armada_xp_cpuidle_device);
-	cpu_pm_register_notifier(&armada_370_xp_cpu_pm_notifier);
+	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
+	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
+	platform_device_register(&mvebu_v7_cpuidle_device);
+	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
 
 	return 0;
 }
 
-arch_initcall(armada_370_xp_cpu_pm_init);
-early_initcall(armada_370_xp_pmsu_init);
+arch_initcall(mvebu_v7_cpu_pm_init);
+early_initcall(mvebu_v7_pmsu_init);
-- 
1.8.1.2


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

* [PATCH 06/16] ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

Actually most of the function related to the PMSU are not specific to
the Armada 370 or Armada XP SoCs, but can also be used for most of the
other mvebu ARMv7 SoCs.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index cdc6d87d0b49..087157c20b8a 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -79,7 +79,7 @@ extern void armada_370_xp_cpu_resume(void);
 static unsigned long pmsu_mp_phys_base;
 static void __iomem *pmsu_mp_base;
 
-static struct platform_device armada_xp_cpuidle_device = {
+static struct platform_device mvebu_v7_cpuidle_device = {
 	.name = "cpuidle-armada-370-xp",
 };
 
@@ -118,7 +118,7 @@ void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
 	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
 }
 
-static int __init armada_370_xp_pmsu_init(void)
+static int __init mvebu_v7_pmsu_init(void)
 {
 	struct device_node *np;
 	struct resource res;
@@ -164,7 +164,7 @@ static int __init armada_370_xp_pmsu_init(void)
 	return ret;
 }
 
-static void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void)
+static void mvebu_v7_pmsu_enable_l2_powerdown_onidle(void)
 {
 	u32 reg;
 
@@ -178,7 +178,7 @@ static void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void)
 }
 
 /* No locking is needed because we only access per-CPU registers */
-void armada_370_xp_pmsu_idle_prepare(bool deepidle)
+static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
 {
 	unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
 	u32 reg;
@@ -215,9 +215,9 @@ void armada_370_xp_pmsu_idle_prepare(bool deepidle)
 	writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
 }
 
-static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
+static noinline int do_armada_xp_370_cpu_suspend(unsigned long deepidle)
 {
-	armada_370_xp_pmsu_idle_prepare(deepidle);
+	mvebu_v7_pmsu_idle_prepare(deepidle);
 
 	v7_exit_coherency_flush(all);
 
@@ -248,13 +248,13 @@ static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
 	return 0;
 }
 
-static int armada_370_xp_cpu_suspend(unsigned long deepidle)
+static int armada_xp_370_cpu_suspend(unsigned long deepidle)
 {
-	return cpu_suspend(deepidle, do_armada_370_xp_cpu_suspend);
+	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
 }
 
 /* No locking is needed because we only access per-CPU registers */
-static noinline void armada_370_xp_pmsu_idle_restore(void)
+static noinline void mvebu_v7_pmsu_idle_restore(void)
 {
 	unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
 	u32 reg;
@@ -276,24 +276,24 @@ static noinline void armada_370_xp_pmsu_idle_restore(void)
 	writel(reg, pmsu_mp_base + PMSU_STATUS_AND_MASK(hw_cpu));
 }
 
-static int armada_370_xp_cpu_pm_notify(struct notifier_block *self,
+static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
 				    unsigned long action, void *hcpu)
 {
 	if (action == CPU_PM_ENTER) {
 		unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
 		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
 	} else if (action == CPU_PM_EXIT) {
-		armada_370_xp_pmsu_idle_restore();
+		mvebu_v7_pmsu_idle_restore();
 	}
 
 	return NOTIFY_OK;
 }
 
-static struct notifier_block armada_370_xp_cpu_pm_notifier = {
-	.notifier_call = armada_370_xp_cpu_pm_notify,
+static struct notifier_block mvebu_v7_cpu_pm_notifier = {
+	.notifier_call = mvebu_v7_cpu_pm_notify,
 };
 
-int __init armada_370_xp_cpu_pm_init(void)
+static int __init mvebu_v7_cpu_pm_init(void)
 {
 	struct device_node *np;
 
@@ -328,13 +328,13 @@ int __init armada_370_xp_cpu_pm_init(void)
 		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
 				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
 
-	armada_370_xp_pmsu_enable_l2_powerdown_onidle();
-	armada_xp_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
-	platform_device_register(&armada_xp_cpuidle_device);
-	cpu_pm_register_notifier(&armada_370_xp_cpu_pm_notifier);
+	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
+	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
+	platform_device_register(&mvebu_v7_cpuidle_device);
+	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
 
 	return 0;
 }
 
-arch_initcall(armada_370_xp_cpu_pm_init);
-early_initcall(armada_370_xp_pmsu_init);
+arch_initcall(mvebu_v7_cpu_pm_init);
+early_initcall(mvebu_v7_pmsu_init);
-- 
1.8.1.2

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

* [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

In order to support more mvebu SoCs, this patch use an initialization
specific function associated to each SoCs which support CPU Idle.

Then each SoC will have his own set of check and of data
configuration.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 087157c20b8a..454f0f9ede6b 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -293,23 +293,47 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
 	.notifier_call = mvebu_v7_cpu_pm_notify,
 };
 
+static bool (*mvebu_v7_cpu_idle_init)(void);
+
+static __init bool armada_xp_cpuidle_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
+	if (!np)
+		return false;
+	of_node_put(np);
+
+	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
+	return true;
+}
+
+static struct of_device_id of_cpuidle_table[] __initdata = {
+	{ .compatible = "marvell,armadaxp",
+	  .data = (void *)armada_xp_cpuidle_init,
+	},
+	{ /* end of list */ },
+};
+
 static int __init mvebu_v7_cpu_pm_init(void)
 {
 	struct device_node *np;
+	const struct of_device_id *match;
+
+	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
+					&match);
+
 
 	/*
 	 * Check that all the requirements are available to enable
-	 * cpuidle. So far, it is only supported on Armada XP, cpuidle
-	 * needs the coherency fabric and the PMSU enabled
+	 * cpuidle. Each SoCs comes with its own requirements and
+	 * configuration
 	 */
 
-	if (!of_machine_is_compatible("marvell,armadaxp"))
-		return 0;
+	mvebu_v7_cpu_idle_init = (bool (*)(void))match->data;
 
-	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
-	if (!np)
+	if (!mvebu_v7_cpu_idle_init())
 		return 0;
-	of_node_put(np);
 
 	np = of_find_matching_node(NULL, of_pmsu_table);
 	if (!np)
@@ -329,7 +353,6 @@ static int __init mvebu_v7_cpu_pm_init(void)
 				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
 
 	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
-	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
 	platform_device_register(&mvebu_v7_cpuidle_device);
 	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
 
-- 
1.8.1.2


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

* [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

In order to support more mvebu SoCs, this patch use an initialization
specific function associated to each SoCs which support CPU Idle.

Then each SoC will have his own set of check and of data
configuration.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 087157c20b8a..454f0f9ede6b 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -293,23 +293,47 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
 	.notifier_call = mvebu_v7_cpu_pm_notify,
 };
 
+static bool (*mvebu_v7_cpu_idle_init)(void);
+
+static __init bool armada_xp_cpuidle_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
+	if (!np)
+		return false;
+	of_node_put(np);
+
+	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
+	return true;
+}
+
+static struct of_device_id of_cpuidle_table[] __initdata = {
+	{ .compatible = "marvell,armadaxp",
+	  .data = (void *)armada_xp_cpuidle_init,
+	},
+	{ /* end of list */ },
+};
+
 static int __init mvebu_v7_cpu_pm_init(void)
 {
 	struct device_node *np;
+	const struct of_device_id *match;
+
+	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
+					&match);
+
 
 	/*
 	 * Check that all the requirements are available to enable
-	 * cpuidle. So far, it is only supported on Armada XP, cpuidle
-	 * needs the coherency fabric and the PMSU enabled
+	 * cpuidle. Each SoCs comes with its own requirements and
+	 * configuration
 	 */
 
-	if (!of_machine_is_compatible("marvell,armadaxp"))
-		return 0;
+	mvebu_v7_cpu_idle_init = (bool (*)(void))match->data;
 
-	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
-	if (!np)
+	if (!mvebu_v7_cpu_idle_init())
 		return 0;
-	of_node_put(np);
 
 	np = of_find_matching_node(NULL, of_pmsu_table);
 	if (!np)
@@ -329,7 +353,6 @@ static int __init mvebu_v7_cpu_pm_init(void)
 				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
 
 	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
-	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
 	platform_device_register(&mvebu_v7_cpuidle_device);
 	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
 
-- 
1.8.1.2

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

* [PATCH 08/16] ARM: mvebu: Use a local variable to store the resume address
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

The resume address used by the cpu idle code will not always be the
same. Using a local variable to store the resume address allows to
keep the same function for the pm notifier but with a different
address. This address will be set during the initialization.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 454f0f9ede6b..8bf737fb3aac 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -79,6 +79,8 @@ extern void armada_370_xp_cpu_resume(void);
 static unsigned long pmsu_mp_phys_base;
 static void __iomem *pmsu_mp_base;
 
+static void *mvebu_cpu_resume;
+
 static struct platform_device mvebu_v7_cpuidle_device = {
 	.name = "cpuidle-armada-370-xp",
 };
@@ -281,7 +283,7 @@ static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
 {
 	if (action == CPU_PM_ENTER) {
 		unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
-		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
+		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cpu_resume);
 	} else if (action == CPU_PM_EXIT) {
 		mvebu_v7_pmsu_idle_restore();
 	}
@@ -304,6 +306,7 @@ static __init bool armada_xp_cpuidle_init(void)
 		return false;
 	of_node_put(np);
 
+	mvebu_cpu_resume = armada_370_xp_cpu_resume;
 	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
 	return true;
 }
-- 
1.8.1.2


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

* [PATCH 08/16] ARM: mvebu: Use a local variable to store the resume address
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

The resume address used by the cpu idle code will not always be the
same. Using a local variable to store the resume address allows to
keep the same function for the pm notifier but with a different
address. This address will be set during the initialization.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 454f0f9ede6b..8bf737fb3aac 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -79,6 +79,8 @@ extern void armada_370_xp_cpu_resume(void);
 static unsigned long pmsu_mp_phys_base;
 static void __iomem *pmsu_mp_base;
 
+static void *mvebu_cpu_resume;
+
 static struct platform_device mvebu_v7_cpuidle_device = {
 	.name = "cpuidle-armada-370-xp",
 };
@@ -281,7 +283,7 @@ static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
 {
 	if (action == CPU_PM_ENTER) {
 		unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
-		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
+		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cpu_resume);
 	} else if (action == CPU_PM_EXIT) {
 		mvebu_v7_pmsu_idle_restore();
 	}
@@ -304,6 +306,7 @@ static __init bool armada_xp_cpuidle_init(void)
 		return false;
 	of_node_put(np);
 
+	mvebu_cpu_resume = armada_370_xp_cpu_resume;
 	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
 	return true;
 }
-- 
1.8.1.2

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

* [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

On some mvebu v7 SoC (the ones which don't use PJ4B core) there is no
such feature. So add a parameter in mvebu_v7_pmsu_idle_prepare function
to make its use optional.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 8bf737fb3aac..a2869c5daeb0 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -180,7 +180,7 @@ static void mvebu_v7_pmsu_enable_l2_powerdown_onidle(void)
 }
 
 /* No locking is needed because we only access per-CPU registers */
-static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
+static void mvebu_v7_pmsu_idle_prepare(bool deepidle, bool snoopdis)
 {
 	unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
 	u32 reg;
@@ -211,15 +211,17 @@ static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
 	reg |= PMSU_CONTROL_AND_CONFIG_PWDDN_REQ;
 	writel(reg, pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
 
-	/* Disable snoop disable by HW - SW is taking care of it */
-	reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
-	reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
-	writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+	if (snoopdis) {
+		/* Disable snoop disable by HW - SW is taking care of it */
+		reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+		reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
+		writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+	}
 }
 
 static noinline int do_armada_xp_370_cpu_suspend(unsigned long deepidle)
 {
-	mvebu_v7_pmsu_idle_prepare(deepidle);
+	mvebu_v7_pmsu_idle_prepare(deepidle, true);
 
 	v7_exit_coherency_flush(all);
 
-- 
1.8.1.2


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

* [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

On some mvebu v7 SoC (the ones which don't use PJ4B core) there is no
such feature. So add a parameter in mvebu_v7_pmsu_idle_prepare function
to make its use optional.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 8bf737fb3aac..a2869c5daeb0 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -180,7 +180,7 @@ static void mvebu_v7_pmsu_enable_l2_powerdown_onidle(void)
 }
 
 /* No locking is needed because we only access per-CPU registers */
-static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
+static void mvebu_v7_pmsu_idle_prepare(bool deepidle, bool snoopdis)
 {
 	unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
 	u32 reg;
@@ -211,15 +211,17 @@ static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
 	reg |= PMSU_CONTROL_AND_CONFIG_PWDDN_REQ;
 	writel(reg, pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
 
-	/* Disable snoop disable by HW - SW is taking care of it */
-	reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
-	reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
-	writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+	if (snoopdis) {
+		/* Disable snoop disable by HW - SW is taking care of it */
+		reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+		reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
+		writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
+	}
 }
 
 static noinline int do_armada_xp_370_cpu_suspend(unsigned long deepidle)
 {
-	mvebu_v7_pmsu_idle_prepare(deepidle);
+	mvebu_v7_pmsu_idle_prepare(deepidle, true);
 
 	v7_exit_coherency_flush(all);
 
-- 
1.8.1.2

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

* [PATCH 10/16] ARM: mvebu: Export the SCU address
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

The SCU address will be needed in other files than the board file, for
example in pmsu.c. So this patch adds a function allowing to get the
SCU address.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/board-v7.c | 9 +++++++--
 arch/arm/mach-mvebu/common.h   | 2 ++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
index 8bb742fdf5ca..4c1d955f51c0 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -33,14 +33,14 @@
 #include "coherency.h"
 #include "mvebu-soc-id.h"
 
+static void __iomem *scu_base;
+
 /*
  * Enables the SCU when available. Obviously, this is only useful on
  * Cortex-A based SOCs, not on PJ4B based ones.
  */
 static void __init mvebu_scu_enable(void)
 {
-	void __iomem *scu_base;
-
 	struct device_node *np =
 		of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
 	if (np) {
@@ -50,6 +50,11 @@ static void __init mvebu_scu_enable(void)
 	}
 }
 
+void __iomem *mvebu_get_scu_base(void)
+{
+	return scu_base;
+}
+
 /*
  * Early versions of Armada 375 SoC have a bug where the BootROM
  * leaves an external data abort pending. The kernel is hit by this
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 6ad62cf8352c..9beb0c45ba59 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -25,4 +25,6 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
 
 void armada_xp_cpu_die(unsigned int cpu);
 
+void __iomem *mvebu_get_scu_base(void);
+
 #endif
-- 
1.8.1.2


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

* [PATCH 10/16] ARM: mvebu: Export the SCU address
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

The SCU address will be needed in other files than the board file, for
example in pmsu.c. So this patch adds a function allowing to get the
SCU address.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/board-v7.c | 9 +++++++--
 arch/arm/mach-mvebu/common.h   | 2 ++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
index 8bb742fdf5ca..4c1d955f51c0 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -33,14 +33,14 @@
 #include "coherency.h"
 #include "mvebu-soc-id.h"
 
+static void __iomem *scu_base;
+
 /*
  * Enables the SCU when available. Obviously, this is only useful on
  * Cortex-A based SOCs, not on PJ4B based ones.
  */
 static void __init mvebu_scu_enable(void)
 {
-	void __iomem *scu_base;
-
 	struct device_node *np =
 		of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
 	if (np) {
@@ -50,6 +50,11 @@ static void __init mvebu_scu_enable(void)
 	}
 }
 
+void __iomem *mvebu_get_scu_base(void)
+{
+	return scu_base;
+}
+
 /*
  * Early versions of Armada 375 SoC have a bug where the BootROM
  * leaves an external data abort pending. The kernel is hit by this
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 6ad62cf8352c..9beb0c45ba59 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -25,4 +25,6 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
 
 void armada_xp_cpu_die(unsigned int cpu);
 
+void __iomem *mvebu_get_scu_base(void);
+
 #endif
-- 
1.8.1.2

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

* [PATCH 11/16] ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai, devicetree

The CA9 MPcore SoC Control block allows to do some configuration that
the SoC could use for a specific use case. In most cases the defaults
case is enough. However there is few exception: for cpuidle we need to
use the CA9 MPcore Reset Control register.

The documentation is also updated in the same time.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Cc: devicetree@vger.kernel.org
---
 .../devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt | 14 ++++++++++++++
 arch/arm/boot/dts/armada-38x.dtsi                          |  5 +++++
 2 files changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt

diff --git a/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt b/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
new file mode 100644
index 000000000000..0a2df51ba560
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
@@ -0,0 +1,14 @@
+Marvell Armada 38x CA9 MPcore SoC Controller
+============================================
+
+Required properties:
+
+- compatible: Should be "marvell,armada-380-mpcore-soc-ctrl".
+
+- reg: should be register base and length as documented in the
+  datasheet for the CA9 MPcore SoC Control registers
+
+mpcore-soc-ctrl@20d20 {
+	compatible = "marvell,armada-380-mpcore-soc-ctrl";
+	reg = <0x20d20 0x6c>;
+};
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index 689fa1a46728..242d0ecc99f3 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -286,6 +286,11 @@
 				reg = <0x20800 0x10>;
 			};
 
+			mpcore-soc-ctrl@20d20 {
+				compatible = "marvell,armada-380-mpcore-soc-ctrl";
+				reg = <0x20d20 0x6c>;
+			};
+
 			coherency-fabric@21010 {
 				compatible = "marvell,armada-380-coherency-fabric";
 				reg = <0x21010 0x1c>;
-- 
1.8.1.2


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

* [PATCH 11/16] ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

The CA9 MPcore SoC Control block allows to do some configuration that
the SoC could use for a specific use case. In most cases the defaults
case is enough. However there is few exception: for cpuidle we need to
use the CA9 MPcore Reset Control register.

The documentation is also updated in the same time.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Cc: devicetree at vger.kernel.org
---
 .../devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt | 14 ++++++++++++++
 arch/arm/boot/dts/armada-38x.dtsi                          |  5 +++++
 2 files changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt

diff --git a/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt b/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
new file mode 100644
index 000000000000..0a2df51ba560
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
@@ -0,0 +1,14 @@
+Marvell Armada 38x CA9 MPcore SoC Controller
+============================================
+
+Required properties:
+
+- compatible: Should be "marvell,armada-380-mpcore-soc-ctrl".
+
+- reg: should be register base and length as documented in the
+  datasheet for the CA9 MPcore SoC Control registers
+
+mpcore-soc-ctrl at 20d20 {
+	compatible = "marvell,armada-380-mpcore-soc-ctrl";
+	reg = <0x20d20 0x6c>;
+};
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index 689fa1a46728..242d0ecc99f3 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -286,6 +286,11 @@
 				reg = <0x20800 0x10>;
 			};
 
+			mpcore-soc-ctrl at 20d20 {
+				compatible = "marvell,armada-380-mpcore-soc-ctrl";
+				reg = <0x20d20 0x6c>;
+			};
+
 			coherency-fabric at 21010 {
 				compatible = "marvell,armada-380-coherency-fabric";
 				reg = <0x21010 0x1c>;
-- 
1.8.1.2

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

* [PATCH 12/16] cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Actually this driver will be able to manage the cpuidle for more SoCs
that Armada 370 ad XP. It will support Armada 38x and potentially
Armada 375. This patch change the names accordingly to this behavior.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c              |  2 +-
 drivers/cpuidle/Kconfig.arm             |  6 +--
 drivers/cpuidle/Makefile                |  2 +-
 drivers/cpuidle/cpuidle-armada-370-xp.c | 93 ---------------------------------
 drivers/cpuidle/cpuidle-mvebu-v7.c      | 93 +++++++++++++++++++++++++++++++++
 5 files changed, 98 insertions(+), 98 deletions(-)
 delete mode 100644 drivers/cpuidle/cpuidle-armada-370-xp.c
 create mode 100644 drivers/cpuidle/cpuidle-mvebu-v7.c

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index a2869c5daeb0..00ebd5638633 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -82,7 +82,7 @@ static void __iomem *pmsu_mp_base;
 static void *mvebu_cpu_resume;
 
 static struct platform_device mvebu_v7_cpuidle_device = {
-	.name = "cpuidle-armada-370-xp",
+	.name = "cpuidle-mvebu-v7",
 };
 
 static struct of_device_id of_pmsu_table[] = {
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index b6d69e899f5d..e4fc2fc66e9f 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -1,11 +1,11 @@
 #
 # ARM CPU Idle drivers
 #
-config ARM_ARMADA_370_XP_CPUIDLE
-	bool "CPU Idle Driver for Armada 370/XP family processors"
+config ARM_MVEBU_V7_CPUIDLE
+	bool "CPU Idle Driver for mvebu v7 family processors"
 	depends on ARCH_MVEBU
 	help
-	  Select this to enable cpuidle on Armada 370/XP processors.
+	  Select this to enable cpuidle on Armada 370, 385 and XP processors.
 
 config ARM_BIG_LITTLE_CPUIDLE
 	bool "Support for ARM big.LITTLE processors"
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index d8bb1ff72561..11edb31c55e9 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
 
 ##################################################################################
 # ARM SoC drivers
-obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o
+obj-$(CONFIG_ARM_MVEBU_V7_CPUIDLE) += cpuidle-mvebu-v7.o
 obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE)	+= cpuidle-big_little.o
 obj-$(CONFIG_ARM_CLPS711X_CPUIDLE)	+= cpuidle-clps711x.o
 obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE)	+= cpuidle-calxeda.o
diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c
deleted file mode 100644
index a5fba0287bfb..000000000000
--- a/drivers/cpuidle/cpuidle-armada-370-xp.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Marvell Armada 370 and Armada XP SoC cpuidle driver
- *
- * Copyright (C) 2014 Marvell
- *
- * Nadav Haklai <nadavh@marvell.com>
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- *
- * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com>
- */
-
-#include <linux/cpu_pm.h>
-#include <linux/cpuidle.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/suspend.h>
-#include <linux/platform_device.h>
-#include <asm/cpuidle.h>
-
-#define ARMADA_370_XP_MAX_STATES	3
-#define ARMADA_370_XP_FLAG_DEEP_IDLE	0x10000
-
-static int (*armada_370_xp_cpu_suspend)(int);
-
-static int armada_370_xp_enter_idle(struct cpuidle_device *dev,
-				struct cpuidle_driver *drv,
-				int index)
-{
-	int ret;
-	bool deepidle = false;
-	cpu_pm_enter();
-
-	if (drv->states[index].flags & ARMADA_370_XP_FLAG_DEEP_IDLE)
-		deepidle = true;
-
-	ret = armada_370_xp_cpu_suspend(deepidle);
-	if (ret)
-		return ret;
-
-	cpu_pm_exit();
-
-	return index;
-}
-
-static struct cpuidle_driver armada_370_xp_idle_driver = {
-	.name			= "armada_370_xp_idle",
-	.states[0]		= ARM_CPUIDLE_WFI_STATE,
-	.states[1]		= {
-		.enter			= armada_370_xp_enter_idle,
-		.exit_latency		= 10,
-		.power_usage		= 50,
-		.target_residency	= 100,
-		.flags			= CPUIDLE_FLAG_TIME_VALID,
-		.name			= "Idle",
-		.desc			= "CPU power down",
-	},
-	.states[2]		= {
-		.enter			= armada_370_xp_enter_idle,
-		.exit_latency		= 100,
-		.power_usage		= 5,
-		.target_residency	= 1000,
-		.flags			= CPUIDLE_FLAG_TIME_VALID |
-						ARMADA_370_XP_FLAG_DEEP_IDLE,
-		.name			= "Deep idle",
-		.desc			= "CPU and L2 Fabric power down",
-	},
-	.state_count = ARMADA_370_XP_MAX_STATES,
-};
-
-static int armada_370_xp_cpuidle_probe(struct platform_device *pdev)
-{
-
-	armada_370_xp_cpu_suspend = (void *)(pdev->dev.platform_data);
-	return cpuidle_register(&armada_370_xp_idle_driver, NULL);
-}
-
-static struct platform_driver armada_370_xp_cpuidle_plat_driver = {
-	.driver = {
-		.name = "cpuidle-armada-370-xp",
-		.owner = THIS_MODULE,
-	},
-	.probe = armada_370_xp_cpuidle_probe,
-};
-
-module_platform_driver(armada_370_xp_cpuidle_plat_driver);
-
-MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
-MODULE_DESCRIPTION("Armada 370/XP cpu idle driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
new file mode 100644
index 000000000000..6066e0d9aabe
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
@@ -0,0 +1,93 @@
+/*
+ * Marvell Armada 370 and Armada XP SoC cpuidle driver
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Nadav Haklai <nadavh@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com>
+ */
+
+#include <linux/cpu_pm.h>
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/suspend.h>
+#include <linux/platform_device.h>
+#include <asm/cpuidle.h>
+
+#define MVEBU_V7_MAX_STATES	3
+#define MVEBU_V7_FLAG_DEEP_IDLE	0x10000
+
+static int (*mvebu_v7_cpu_suspend)(int);
+
+static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
+				struct cpuidle_driver *drv,
+				int index)
+{
+	int ret;
+	bool deepidle = false;
+	cpu_pm_enter();
+
+	if (drv->states[index].flags & MVEBU_V7_FLAG_DEEP_IDLE)
+		deepidle = true;
+
+	ret = mvebu_v7_cpu_suspend(deepidle);
+	if (ret)
+		return ret;
+
+	cpu_pm_exit();
+
+	return index;
+}
+
+static struct cpuidle_driver mvebu_v7_idle_driver = {
+	.name			= "mvebu_v7_idle",
+	.states[0]		= ARM_CPUIDLE_WFI_STATE,
+	.states[1]		= {
+		.enter			= mvebu_v7_enter_idle,
+		.exit_latency		= 10,
+		.power_usage		= 50,
+		.target_residency	= 100,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "Idle",
+		.desc			= "CPU power down",
+	},
+	.states[2]		= {
+		.enter			= mvebu_v7_enter_idle,
+		.exit_latency		= 100,
+		.power_usage		= 5,
+		.target_residency	= 1000,
+		.flags			= CPUIDLE_FLAG_TIME_VALID |
+						MVEBU_V7_FLAG_DEEP_IDLE,
+		.name			= "Deep idle",
+		.desc			= "CPU and L2 Fabric power down",
+	},
+	.state_count = MVEBU_V7_MAX_STATES,
+};
+
+static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
+{
+
+	mvebu_v7_cpu_suspend = (void *)(pdev->dev.platform_data);
+	return cpuidle_register(&mvebu_v7_idle_driver, NULL);
+}
+
+static struct platform_driver mvebu_v7_cpuidle_plat_driver = {
+	.driver = {
+		.name = "cpuidle-mvebu-v7",
+		.owner = THIS_MODULE,
+	},
+	.probe = mvebu_v7_cpuidle_probe,
+};
+
+module_platform_driver(mvebu_v7_cpuidle_plat_driver);
+
+MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
+MODULE_DESCRIPTION("Mvebu v7 cpu idle driver");
+MODULE_LICENSE("GPL");
-- 
1.8.1.2


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

* [PATCH 12/16] cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

Actually this driver will be able to manage the cpuidle for more SoCs
that Armada 370 ad XP. It will support Armada 38x and potentially
Armada 375. This patch change the names accordingly to this behavior.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c              |  2 +-
 drivers/cpuidle/Kconfig.arm             |  6 +--
 drivers/cpuidle/Makefile                |  2 +-
 drivers/cpuidle/cpuidle-armada-370-xp.c | 93 ---------------------------------
 drivers/cpuidle/cpuidle-mvebu-v7.c      | 93 +++++++++++++++++++++++++++++++++
 5 files changed, 98 insertions(+), 98 deletions(-)
 delete mode 100644 drivers/cpuidle/cpuidle-armada-370-xp.c
 create mode 100644 drivers/cpuidle/cpuidle-mvebu-v7.c

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index a2869c5daeb0..00ebd5638633 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -82,7 +82,7 @@ static void __iomem *pmsu_mp_base;
 static void *mvebu_cpu_resume;
 
 static struct platform_device mvebu_v7_cpuidle_device = {
-	.name = "cpuidle-armada-370-xp",
+	.name = "cpuidle-mvebu-v7",
 };
 
 static struct of_device_id of_pmsu_table[] = {
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index b6d69e899f5d..e4fc2fc66e9f 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -1,11 +1,11 @@
 #
 # ARM CPU Idle drivers
 #
-config ARM_ARMADA_370_XP_CPUIDLE
-	bool "CPU Idle Driver for Armada 370/XP family processors"
+config ARM_MVEBU_V7_CPUIDLE
+	bool "CPU Idle Driver for mvebu v7 family processors"
 	depends on ARCH_MVEBU
 	help
-	  Select this to enable cpuidle on Armada 370/XP processors.
+	  Select this to enable cpuidle on Armada 370, 385 and XP processors.
 
 config ARM_BIG_LITTLE_CPUIDLE
 	bool "Support for ARM big.LITTLE processors"
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index d8bb1ff72561..11edb31c55e9 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
 
 ##################################################################################
 # ARM SoC drivers
-obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o
+obj-$(CONFIG_ARM_MVEBU_V7_CPUIDLE) += cpuidle-mvebu-v7.o
 obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE)	+= cpuidle-big_little.o
 obj-$(CONFIG_ARM_CLPS711X_CPUIDLE)	+= cpuidle-clps711x.o
 obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE)	+= cpuidle-calxeda.o
diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c
deleted file mode 100644
index a5fba0287bfb..000000000000
--- a/drivers/cpuidle/cpuidle-armada-370-xp.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Marvell Armada 370 and Armada XP SoC cpuidle driver
- *
- * Copyright (C) 2014 Marvell
- *
- * Nadav Haklai <nadavh@marvell.com>
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- *
- * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com>
- */
-
-#include <linux/cpu_pm.h>
-#include <linux/cpuidle.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/suspend.h>
-#include <linux/platform_device.h>
-#include <asm/cpuidle.h>
-
-#define ARMADA_370_XP_MAX_STATES	3
-#define ARMADA_370_XP_FLAG_DEEP_IDLE	0x10000
-
-static int (*armada_370_xp_cpu_suspend)(int);
-
-static int armada_370_xp_enter_idle(struct cpuidle_device *dev,
-				struct cpuidle_driver *drv,
-				int index)
-{
-	int ret;
-	bool deepidle = false;
-	cpu_pm_enter();
-
-	if (drv->states[index].flags & ARMADA_370_XP_FLAG_DEEP_IDLE)
-		deepidle = true;
-
-	ret = armada_370_xp_cpu_suspend(deepidle);
-	if (ret)
-		return ret;
-
-	cpu_pm_exit();
-
-	return index;
-}
-
-static struct cpuidle_driver armada_370_xp_idle_driver = {
-	.name			= "armada_370_xp_idle",
-	.states[0]		= ARM_CPUIDLE_WFI_STATE,
-	.states[1]		= {
-		.enter			= armada_370_xp_enter_idle,
-		.exit_latency		= 10,
-		.power_usage		= 50,
-		.target_residency	= 100,
-		.flags			= CPUIDLE_FLAG_TIME_VALID,
-		.name			= "Idle",
-		.desc			= "CPU power down",
-	},
-	.states[2]		= {
-		.enter			= armada_370_xp_enter_idle,
-		.exit_latency		= 100,
-		.power_usage		= 5,
-		.target_residency	= 1000,
-		.flags			= CPUIDLE_FLAG_TIME_VALID |
-						ARMADA_370_XP_FLAG_DEEP_IDLE,
-		.name			= "Deep idle",
-		.desc			= "CPU and L2 Fabric power down",
-	},
-	.state_count = ARMADA_370_XP_MAX_STATES,
-};
-
-static int armada_370_xp_cpuidle_probe(struct platform_device *pdev)
-{
-
-	armada_370_xp_cpu_suspend = (void *)(pdev->dev.platform_data);
-	return cpuidle_register(&armada_370_xp_idle_driver, NULL);
-}
-
-static struct platform_driver armada_370_xp_cpuidle_plat_driver = {
-	.driver = {
-		.name = "cpuidle-armada-370-xp",
-		.owner = THIS_MODULE,
-	},
-	.probe = armada_370_xp_cpuidle_probe,
-};
-
-module_platform_driver(armada_370_xp_cpuidle_plat_driver);
-
-MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
-MODULE_DESCRIPTION("Armada 370/XP cpu idle driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
new file mode 100644
index 000000000000..6066e0d9aabe
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
@@ -0,0 +1,93 @@
+/*
+ * Marvell Armada 370 and Armada XP SoC cpuidle driver
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Nadav Haklai <nadavh@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com>
+ */
+
+#include <linux/cpu_pm.h>
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/suspend.h>
+#include <linux/platform_device.h>
+#include <asm/cpuidle.h>
+
+#define MVEBU_V7_MAX_STATES	3
+#define MVEBU_V7_FLAG_DEEP_IDLE	0x10000
+
+static int (*mvebu_v7_cpu_suspend)(int);
+
+static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
+				struct cpuidle_driver *drv,
+				int index)
+{
+	int ret;
+	bool deepidle = false;
+	cpu_pm_enter();
+
+	if (drv->states[index].flags & MVEBU_V7_FLAG_DEEP_IDLE)
+		deepidle = true;
+
+	ret = mvebu_v7_cpu_suspend(deepidle);
+	if (ret)
+		return ret;
+
+	cpu_pm_exit();
+
+	return index;
+}
+
+static struct cpuidle_driver mvebu_v7_idle_driver = {
+	.name			= "mvebu_v7_idle",
+	.states[0]		= ARM_CPUIDLE_WFI_STATE,
+	.states[1]		= {
+		.enter			= mvebu_v7_enter_idle,
+		.exit_latency		= 10,
+		.power_usage		= 50,
+		.target_residency	= 100,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "Idle",
+		.desc			= "CPU power down",
+	},
+	.states[2]		= {
+		.enter			= mvebu_v7_enter_idle,
+		.exit_latency		= 100,
+		.power_usage		= 5,
+		.target_residency	= 1000,
+		.flags			= CPUIDLE_FLAG_TIME_VALID |
+						MVEBU_V7_FLAG_DEEP_IDLE,
+		.name			= "Deep idle",
+		.desc			= "CPU and L2 Fabric power down",
+	},
+	.state_count = MVEBU_V7_MAX_STATES,
+};
+
+static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
+{
+
+	mvebu_v7_cpu_suspend = (void *)(pdev->dev.platform_data);
+	return cpuidle_register(&mvebu_v7_idle_driver, NULL);
+}
+
+static struct platform_driver mvebu_v7_cpuidle_plat_driver = {
+	.driver = {
+		.name = "cpuidle-mvebu-v7",
+		.owner = THIS_MODULE,
+	},
+	.probe = mvebu_v7_cpuidle_probe,
+};
+
+module_platform_driver(mvebu_v7_cpuidle_plat_driver);
+
+MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
+MODULE_DESCRIPTION("Mvebu v7 cpu idle driver");
+MODULE_LICENSE("GPL");
-- 
1.8.1.2

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

* [PATCH 13/16] cpuidle: mvebu: Move the description of the cpuidle states in the platform part
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

In order to prepare the add of new SoCs supports for this cpuidle
driver, this patch moves the description of the state in the platform
part. Indeed the number of the cpuidle state, and the value of the
flag used will vary depending of the SoC.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c         | 32 +++++++++++++++++++++++--
 drivers/cpuidle/cpuidle-mvebu-v7.c | 49 +++++++++++++-------------------------
 include/linux/mvebu-v7-cpuidle.h   | 24 +++++++++++++++++++
 3 files changed, 70 insertions(+), 35 deletions(-)
 create mode 100644 include/linux/mvebu-v7-cpuidle.h

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 00ebd5638633..9396839e162e 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -19,15 +19,18 @@
 #define pr_fmt(fmt) "mvebu-pmsu: " fmt
 
 #include <linux/cpu_pm.h>
+#include <linux/cpuidle.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/mbus.h>
+#include <linux/mvebu-v7-cpuidle.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
 #include <linux/smp.h>
 #include <asm/cacheflush.h>
+#include <asm/cpuidle.h>
 #include <asm/cp15.h>
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
@@ -299,17 +302,42 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
 
 static bool (*mvebu_v7_cpu_idle_init)(void);
 
+static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
+	.mvebu_v7_idle_driver = {
+		.name			= "armada_xp_idle",
+		.states[0]		= ARM_CPUIDLE_WFI_STATE,
+		.states[1]		= {
+			.exit_latency		= 10,
+			.power_usage		= 50,
+			.target_residency	= 100,
+			.flags			= CPUIDLE_FLAG_TIME_VALID,
+			.name			= "Idle",
+			.desc			= "CPU power down",
+		},
+		.states[2]		= {
+			.exit_latency		= 100,
+			.power_usage		= 5,
+			.target_residency	= 1000,
+			.flags			= CPUIDLE_FLAG_TIME_VALID |
+			MVEBU_V7_FLAG_DEEP_IDLE,
+			.name			= "Deep idle",
+			.desc			= "CPU and L2 Fabric power down",
+		},
+		.state_count = 3,
+	},
+	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
+};
+
 static __init bool armada_xp_cpuidle_init(void)
 {
 	struct device_node *np;
-
 	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
 	if (!np)
 		return false;
 	of_node_put(np);
 
 	mvebu_cpu_resume = armada_370_xp_cpu_resume;
-	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
+	mvebu_v7_cpuidle_device.dev.platform_data = &armada_xp_cpuidle;
 	return true;
 }
 
diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
index 6066e0d9aabe..2fdc18797c0e 100644
--- a/drivers/cpuidle/cpuidle-mvebu-v7.c
+++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
@@ -16,15 +16,12 @@
 #include <linux/cpu_pm.h>
 #include <linux/cpuidle.h>
 #include <linux/module.h>
+#include <linux/mvebu-v7-cpuidle.h>
 #include <linux/of.h>
 #include <linux/suspend.h>
 #include <linux/platform_device.h>
-#include <asm/cpuidle.h>
 
-#define MVEBU_V7_MAX_STATES	3
-#define MVEBU_V7_FLAG_DEEP_IDLE	0x10000
-
-static int (*mvebu_v7_cpu_suspend)(int);
+static struct mvebu_v7_cpuidle *pcpuidle;
 
 static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
 				struct cpuidle_driver *drv,
@@ -32,12 +29,13 @@ static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
 {
 	int ret;
 	bool deepidle = false;
+
 	cpu_pm_enter();
 
 	if (drv->states[index].flags & MVEBU_V7_FLAG_DEEP_IDLE)
 		deepidle = true;
 
-	ret = mvebu_v7_cpu_suspend(deepidle);
+	ret = pcpuidle->mvebu_v7_cpu_suspend(deepidle);
 	if (ret)
 		return ret;
 
@@ -46,36 +44,21 @@ static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
 	return index;
 }
 
-static struct cpuidle_driver mvebu_v7_idle_driver = {
-	.name			= "mvebu_v7_idle",
-	.states[0]		= ARM_CPUIDLE_WFI_STATE,
-	.states[1]		= {
-		.enter			= mvebu_v7_enter_idle,
-		.exit_latency		= 10,
-		.power_usage		= 50,
-		.target_residency	= 100,
-		.flags			= CPUIDLE_FLAG_TIME_VALID,
-		.name			= "Idle",
-		.desc			= "CPU power down",
-	},
-	.states[2]		= {
-		.enter			= mvebu_v7_enter_idle,
-		.exit_latency		= 100,
-		.power_usage		= 5,
-		.target_residency	= 1000,
-		.flags			= CPUIDLE_FLAG_TIME_VALID |
-						MVEBU_V7_FLAG_DEEP_IDLE,
-		.name			= "Deep idle",
-		.desc			= "CPU and L2 Fabric power down",
-	},
-	.state_count = MVEBU_V7_MAX_STATES,
-};
-
 static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
 {
+	int i;
+
+	pcpuidle = (void *)(pdev->dev.platform_data);
+
+	/*
+	 * The first state is the ARM WFI state, so we don't have to
+	 * provide an enter function
+	 */
+	for (i = 1; i < pcpuidle->mvebu_v7_idle_driver.state_count; i++)
+		pcpuidle->mvebu_v7_idle_driver.states[i].enter =
+			mvebu_v7_enter_idle;
 
-	mvebu_v7_cpu_suspend = (void *)(pdev->dev.platform_data);
-	return cpuidle_register(&mvebu_v7_idle_driver, NULL);
+	return cpuidle_register(&pcpuidle->mvebu_v7_idle_driver, NULL);
 }
 
 static struct platform_driver mvebu_v7_cpuidle_plat_driver = {
diff --git a/include/linux/mvebu-v7-cpuidle.h b/include/linux/mvebu-v7-cpuidle.h
new file mode 100644
index 000000000000..28c8674292ad
--- /dev/null
+++ b/include/linux/mvebu-v7-cpuidle.h
@@ -0,0 +1,24 @@
+/*
+ * Marvell EBU cpuidle defintion
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ */
+
+#ifndef __LINUX_MVEBU_V7_CPUIDLE_H__
+#define __LINUX_MVEBU_V7_CPUIDLE_H__
+
+#define MVEBU_V7_FLAG_DEEP_IDLE	0x10000
+
+struct mvebu_v7_cpuidle {
+	struct cpuidle_driver mvebu_v7_idle_driver;
+	int (*mvebu_v7_cpu_suspend)(unsigned long);
+};
+
+#endif
-- 
1.8.1.2


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

* [PATCH 13/16] cpuidle: mvebu: Move the description of the cpuidle states in the platform part
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

In order to prepare the add of new SoCs supports for this cpuidle
driver, this patch moves the description of the state in the platform
part. Indeed the number of the cpuidle state, and the value of the
flag used will vary depending of the SoC.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c         | 32 +++++++++++++++++++++++--
 drivers/cpuidle/cpuidle-mvebu-v7.c | 49 +++++++++++++-------------------------
 include/linux/mvebu-v7-cpuidle.h   | 24 +++++++++++++++++++
 3 files changed, 70 insertions(+), 35 deletions(-)
 create mode 100644 include/linux/mvebu-v7-cpuidle.h

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 00ebd5638633..9396839e162e 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -19,15 +19,18 @@
 #define pr_fmt(fmt) "mvebu-pmsu: " fmt
 
 #include <linux/cpu_pm.h>
+#include <linux/cpuidle.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/mbus.h>
+#include <linux/mvebu-v7-cpuidle.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
 #include <linux/smp.h>
 #include <asm/cacheflush.h>
+#include <asm/cpuidle.h>
 #include <asm/cp15.h>
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
@@ -299,17 +302,42 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
 
 static bool (*mvebu_v7_cpu_idle_init)(void);
 
+static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
+	.mvebu_v7_idle_driver = {
+		.name			= "armada_xp_idle",
+		.states[0]		= ARM_CPUIDLE_WFI_STATE,
+		.states[1]		= {
+			.exit_latency		= 10,
+			.power_usage		= 50,
+			.target_residency	= 100,
+			.flags			= CPUIDLE_FLAG_TIME_VALID,
+			.name			= "Idle",
+			.desc			= "CPU power down",
+		},
+		.states[2]		= {
+			.exit_latency		= 100,
+			.power_usage		= 5,
+			.target_residency	= 1000,
+			.flags			= CPUIDLE_FLAG_TIME_VALID |
+			MVEBU_V7_FLAG_DEEP_IDLE,
+			.name			= "Deep idle",
+			.desc			= "CPU and L2 Fabric power down",
+		},
+		.state_count = 3,
+	},
+	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
+};
+
 static __init bool armada_xp_cpuidle_init(void)
 {
 	struct device_node *np;
-
 	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
 	if (!np)
 		return false;
 	of_node_put(np);
 
 	mvebu_cpu_resume = armada_370_xp_cpu_resume;
-	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
+	mvebu_v7_cpuidle_device.dev.platform_data = &armada_xp_cpuidle;
 	return true;
 }
 
diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
index 6066e0d9aabe..2fdc18797c0e 100644
--- a/drivers/cpuidle/cpuidle-mvebu-v7.c
+++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
@@ -16,15 +16,12 @@
 #include <linux/cpu_pm.h>
 #include <linux/cpuidle.h>
 #include <linux/module.h>
+#include <linux/mvebu-v7-cpuidle.h>
 #include <linux/of.h>
 #include <linux/suspend.h>
 #include <linux/platform_device.h>
-#include <asm/cpuidle.h>
 
-#define MVEBU_V7_MAX_STATES	3
-#define MVEBU_V7_FLAG_DEEP_IDLE	0x10000
-
-static int (*mvebu_v7_cpu_suspend)(int);
+static struct mvebu_v7_cpuidle *pcpuidle;
 
 static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
 				struct cpuidle_driver *drv,
@@ -32,12 +29,13 @@ static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
 {
 	int ret;
 	bool deepidle = false;
+
 	cpu_pm_enter();
 
 	if (drv->states[index].flags & MVEBU_V7_FLAG_DEEP_IDLE)
 		deepidle = true;
 
-	ret = mvebu_v7_cpu_suspend(deepidle);
+	ret = pcpuidle->mvebu_v7_cpu_suspend(deepidle);
 	if (ret)
 		return ret;
 
@@ -46,36 +44,21 @@ static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
 	return index;
 }
 
-static struct cpuidle_driver mvebu_v7_idle_driver = {
-	.name			= "mvebu_v7_idle",
-	.states[0]		= ARM_CPUIDLE_WFI_STATE,
-	.states[1]		= {
-		.enter			= mvebu_v7_enter_idle,
-		.exit_latency		= 10,
-		.power_usage		= 50,
-		.target_residency	= 100,
-		.flags			= CPUIDLE_FLAG_TIME_VALID,
-		.name			= "Idle",
-		.desc			= "CPU power down",
-	},
-	.states[2]		= {
-		.enter			= mvebu_v7_enter_idle,
-		.exit_latency		= 100,
-		.power_usage		= 5,
-		.target_residency	= 1000,
-		.flags			= CPUIDLE_FLAG_TIME_VALID |
-						MVEBU_V7_FLAG_DEEP_IDLE,
-		.name			= "Deep idle",
-		.desc			= "CPU and L2 Fabric power down",
-	},
-	.state_count = MVEBU_V7_MAX_STATES,
-};
-
 static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
 {
+	int i;
+
+	pcpuidle = (void *)(pdev->dev.platform_data);
+
+	/*
+	 * The first state is the ARM WFI state, so we don't have to
+	 * provide an enter function
+	 */
+	for (i = 1; i < pcpuidle->mvebu_v7_idle_driver.state_count; i++)
+		pcpuidle->mvebu_v7_idle_driver.states[i].enter =
+			mvebu_v7_enter_idle;
 
-	mvebu_v7_cpu_suspend = (void *)(pdev->dev.platform_data);
-	return cpuidle_register(&mvebu_v7_idle_driver, NULL);
+	return cpuidle_register(&pcpuidle->mvebu_v7_idle_driver, NULL);
 }
 
 static struct platform_driver mvebu_v7_cpuidle_plat_driver = {
diff --git a/include/linux/mvebu-v7-cpuidle.h b/include/linux/mvebu-v7-cpuidle.h
new file mode 100644
index 000000000000..28c8674292ad
--- /dev/null
+++ b/include/linux/mvebu-v7-cpuidle.h
@@ -0,0 +1,24 @@
+/*
+ * Marvell EBU cpuidle defintion
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ */
+
+#ifndef __LINUX_MVEBU_V7_CPUIDLE_H__
+#define __LINUX_MVEBU_V7_CPUIDLE_H__
+
+#define MVEBU_V7_FLAG_DEEP_IDLE	0x10000
+
+struct mvebu_v7_cpuidle {
+	struct cpuidle_driver mvebu_v7_idle_driver;
+	int (*mvebu_v7_cpu_suspend)(unsigned long);
+};
+
+#endif
-- 
1.8.1.2

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

* [PATCH 14/16] ARM: mvebu: Add CPU idle support for Armada 370
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Unlike the Armada XP the Armada 370 always power done the L2 cache, so
it have only 2 cpuidle states. Thanks to the previous patches, adding
the support for this new SoCs required only the modification of the
architecture specific part.

The message in case of failure to suspend the system was switched from
warn to debug. Indeed due to the "slow exit process from the deep idle
state" in Armada 370, this situation happens quite often. Using the
_debug version avoids spamming the kernel logs, but still allows to
enable it if needed.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 60 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 9396839e162e..bfd471538811 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -250,7 +250,7 @@ static noinline int do_armada_xp_370_cpu_suspend(unsigned long deepidle)
 	"isb	"
 	: : "r" (0));
 
-	pr_warn("Failed to suspend the system\n");
+	pr_debug("Failed to suspend the system\n");
 
 	return 0;
 }
@@ -302,6 +302,24 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
 
 static bool (*mvebu_v7_cpu_idle_init)(void);
 
+static struct mvebu_v7_cpuidle armada_370_cpuidle = {
+	.mvebu_v7_idle_driver = {
+		.name			= "armada_370_idle",
+		.states[0]		= ARM_CPUIDLE_WFI_STATE,
+		.states[1]		= {
+			.exit_latency		= 100,
+			.power_usage		= 5,
+			.target_residency	= 1000,
+			.flags			= CPUIDLE_FLAG_TIME_VALID |
+			MVEBU_V7_FLAG_DEEP_IDLE,
+			.name			= "Deep Idle",
+			.desc			= "CPU and L2 Fabric power down",
+		},
+		.state_count = 2,
+	},
+	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
+};
+
 static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
 	.mvebu_v7_idle_driver = {
 		.name			= "armada_xp_idle",
@@ -328,6 +346,31 @@ static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
 	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
 };
 
+static __init bool armada_370_cpuidle_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
+	if (!np)
+		return false;
+	of_node_put(np);
+
+	/*
+	 * On Armada 370, there is "a slow exit process from the deep
+	 * idle state due to heavy L1/L2 cache cleanup operations
+	 * performed by the BootROM software". To avoid this, we
+	 * replace the restart code of the bootrom by a a simple jump
+	 * to the boot address. Then the code located at this boot
+	 * address will take care of the initialization.
+	 */
+	mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
+			PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
+
+	mvebu_cpu_resume = armada_370_xp_cpu_resume;
+	mvebu_v7_cpuidle_device.dev.platform_data = &armada_370_cpuidle;
+	return true;
+}
+
 static __init bool armada_xp_cpuidle_init(void)
 {
 	struct device_node *np;
@@ -345,6 +388,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
 	{ .compatible = "marvell,armadaxp",
 	  .data = (void *)armada_xp_cpuidle_init,
 	},
+	{ .compatible = "marvell,armada370",
+	  .data = (void *)armada_370_cpuidle_init,
+	},
 	{ /* end of list */ },
 };
 
@@ -373,18 +419,6 @@ static int __init mvebu_v7_cpu_pm_init(void)
 		return 0;
 	of_node_put(np);
 
-	/*
-	 * On Armada 370, there is "a slow exit process from the deep
-	 * idle state due to heavy L1/L2 cache cleanup operations
-	 * performed by the BootROM software". To avoid this, we
-	 * replace the restart code of the bootrom by a a simple jump
-	 * to the boot address. Then the code located at this boot
-	 * address will take care of the initialization.
-	 */
-	if (of_machine_is_compatible("marvell,armada370"))
-		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
-				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
-
 	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
 	platform_device_register(&mvebu_v7_cpuidle_device);
 	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
-- 
1.8.1.2


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

* [PATCH 14/16] ARM: mvebu: Add CPU idle support for Armada 370
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

Unlike the Armada XP the Armada 370 always power done the L2 cache, so
it have only 2 cpuidle states. Thanks to the previous patches, adding
the support for this new SoCs required only the modification of the
architecture specific part.

The message in case of failure to suspend the system was switched from
warn to debug. Indeed due to the "slow exit process from the deep idle
state" in Armada 370, this situation happens quite often. Using the
_debug version avoids spamming the kernel logs, but still allows to
enable it if needed.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c | 60 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 9396839e162e..bfd471538811 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -250,7 +250,7 @@ static noinline int do_armada_xp_370_cpu_suspend(unsigned long deepidle)
 	"isb	"
 	: : "r" (0));
 
-	pr_warn("Failed to suspend the system\n");
+	pr_debug("Failed to suspend the system\n");
 
 	return 0;
 }
@@ -302,6 +302,24 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
 
 static bool (*mvebu_v7_cpu_idle_init)(void);
 
+static struct mvebu_v7_cpuidle armada_370_cpuidle = {
+	.mvebu_v7_idle_driver = {
+		.name			= "armada_370_idle",
+		.states[0]		= ARM_CPUIDLE_WFI_STATE,
+		.states[1]		= {
+			.exit_latency		= 100,
+			.power_usage		= 5,
+			.target_residency	= 1000,
+			.flags			= CPUIDLE_FLAG_TIME_VALID |
+			MVEBU_V7_FLAG_DEEP_IDLE,
+			.name			= "Deep Idle",
+			.desc			= "CPU and L2 Fabric power down",
+		},
+		.state_count = 2,
+	},
+	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
+};
+
 static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
 	.mvebu_v7_idle_driver = {
 		.name			= "armada_xp_idle",
@@ -328,6 +346,31 @@ static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
 	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
 };
 
+static __init bool armada_370_cpuidle_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
+	if (!np)
+		return false;
+	of_node_put(np);
+
+	/*
+	 * On Armada 370, there is "a slow exit process from the deep
+	 * idle state due to heavy L1/L2 cache cleanup operations
+	 * performed by the BootROM software". To avoid this, we
+	 * replace the restart code of the bootrom by a a simple jump
+	 * to the boot address. Then the code located at this boot
+	 * address will take care of the initialization.
+	 */
+	mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
+			PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
+
+	mvebu_cpu_resume = armada_370_xp_cpu_resume;
+	mvebu_v7_cpuidle_device.dev.platform_data = &armada_370_cpuidle;
+	return true;
+}
+
 static __init bool armada_xp_cpuidle_init(void)
 {
 	struct device_node *np;
@@ -345,6 +388,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
 	{ .compatible = "marvell,armadaxp",
 	  .data = (void *)armada_xp_cpuidle_init,
 	},
+	{ .compatible = "marvell,armada370",
+	  .data = (void *)armada_370_cpuidle_init,
+	},
 	{ /* end of list */ },
 };
 
@@ -373,18 +419,6 @@ static int __init mvebu_v7_cpu_pm_init(void)
 		return 0;
 	of_node_put(np);
 
-	/*
-	 * On Armada 370, there is "a slow exit process from the deep
-	 * idle state due to heavy L1/L2 cache cleanup operations
-	 * performed by the BootROM software". To avoid this, we
-	 * replace the restart code of the bootrom by a a simple jump
-	 * to the boot address. Then the code located at this boot
-	 * address will take care of the initialization.
-	 */
-	if (of_machine_is_compatible("marvell,armada370"))
-		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
-				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
-
 	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
 	platform_device_register(&mvebu_v7_cpuidle_device);
 	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
-- 
1.8.1.2

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

* [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Unlike the Armada XP and the Armada 370, this SoC uses a Cortex A9
core. Beside this, the main difference for the cpu idle is the way to
handle the L2 cache and the use of SCU.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c    | 101 +++++++++++++++++++++++++++++++++++++++++-
 arch/arm/mach-mvebu/pmsu_ll.S |  14 ++++++
 2 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index bfd471538811..3e49fb73c3d5 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -32,6 +32,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cpuidle.h>
 #include <asm/cp15.h>
+#include <asm/smp_scu.h>
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
@@ -66,6 +67,19 @@
 #define L2C_NFABRIC_PM_CTL		    0x4
 #define L2C_NFABRIC_PM_CTL_PWR_DOWN		BIT(20)
 
+/* PMSU delay registers */
+#define PMSU_POWERDOWN_DELAY		    0xF04
+#define PMSU_POWERDOWN_DELAY_PMU		BIT(1)
+#define PMSU_POWERDOWN_DELAY_MASK		0xFFFE
+
+#define PMSU_DFLT_ARMADA38X_DELAY	0x64
+
+/* CA9 MPcore SoC Control registers */
+
+#define MPCORE_RESET_CTL		    0x64
+#define MPCORE_RESET_CTL_L2			BIT(0)
+#define MPCORE_RESET_CTL_DEBUG			BIT(16)
+
 #define ARMADA_370_CRYPT0_ENG_ID	0x9
 #define CRYPT0_ENG_ATTR	0x1
 
@@ -78,10 +92,13 @@ extern void ll_disable_coherency(void);
 extern void ll_enable_coherency(void);
 
 extern void armada_370_xp_cpu_resume(void);
+extern void armada_38x_cpu_resume(void);
 
 static unsigned long pmsu_mp_phys_base;
 static void __iomem *pmsu_mp_base;
 
+static void __iomem *scu_base;
+
 static void *mvebu_cpu_resume;
 
 static struct platform_device mvebu_v7_cpuidle_device = {
@@ -151,6 +168,7 @@ static int __init mvebu_v7_pmsu_init(void)
 				np->full_name)) {
 		pr_err("unable to request region\n");
 		ret = -EBUSY;
+
 		goto out;
 	}
 
@@ -163,7 +181,6 @@ static int __init mvebu_v7_pmsu_init(void)
 		ret = -ENOMEM;
 		goto out;
 	}
-
  out:
 	of_node_put(np);
 	return ret;
@@ -260,6 +277,27 @@ static int armada_xp_370_cpu_suspend(unsigned long deepidle)
 	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
 }
 
+static noinline int do_armada_38x_cpu_suspend(unsigned long deepidle)
+{
+	mvebu_v7_pmsu_idle_prepare(deepidle, false);
+	/*
+	 * Already flushed cache, but do it again as the outer cache
+	 * functions dirty the cache with spinlocks
+	 */
+	v7_exit_coherency_flush(louis);
+
+	scu_power_mode(scu_base, SCU_PM_POWEROFF);
+
+	cpu_do_idle();
+
+	return 1;
+}
+
+static int armada_38x_cpu_suspend(unsigned long deepidle)
+{
+	return cpu_suspend(false, do_armada_38x_cpu_suspend);
+}
+
 /* No locking is needed because we only access per-CPU registers */
 static noinline void mvebu_v7_pmsu_idle_restore(void)
 {
@@ -268,7 +306,6 @@ static noinline void mvebu_v7_pmsu_idle_restore(void)
 
 	if (pmsu_mp_base == NULL)
 		return;
-
 	/* cancel ask HW to power down the L2 Cache if possible */
 	reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
 	reg &= ~PMSU_CONTROL_AND_CONFIG_L2_PWDDN;
@@ -320,6 +357,23 @@ static struct mvebu_v7_cpuidle armada_370_cpuidle = {
 	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
 };
 
+static struct mvebu_v7_cpuidle armada_38x_cpuidle = {
+	.mvebu_v7_idle_driver = {
+		.name			= "armada_38x_idle",
+		.states[0]		= ARM_CPUIDLE_WFI_STATE,
+		.states[1]		= {
+			.exit_latency		= 10,
+			.power_usage		= 5,
+			.target_residency	= 100,
+			.flags			= CPUIDLE_FLAG_TIME_VALID,
+			.name			= "Idle",
+			.desc			= "CPU and SCU power down",
+		},
+		.state_count = 2,
+	},
+	.mvebu_v7_cpu_suspend = armada_38x_cpu_suspend,
+};
+
 static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
 	.mvebu_v7_idle_driver = {
 		.name			= "armada_xp_idle",
@@ -371,6 +425,46 @@ static __init bool armada_370_cpuidle_init(void)
 	return true;
 }
 
+static __init bool armada_38x_cpuidle_init(void)
+{
+	struct device_node *np;
+	void __iomem *mpsoc_base;
+	u32 reg;
+
+	np = of_find_compatible_node(NULL, NULL,
+				"marvell,armada-380-coherency-fabric");
+	if (!np)
+		return false;
+	of_node_put(np);
+
+	np = of_find_compatible_node(NULL, NULL,
+				"marvell,armada-380-mpcore-soc-ctrl");
+	if (!np)
+		return false;
+	mpsoc_base = of_iomap(np, 0);
+	WARN_ON(!mpsoc_base);
+
+	/* Set up reset mask when powering down the cpus */
+	reg = readl(mpsoc_base + MPCORE_RESET_CTL);
+	reg |= MPCORE_RESET_CTL_L2;
+	reg |= MPCORE_RESET_CTL_DEBUG;
+	writel(reg, mpsoc_base + MPCORE_RESET_CTL);
+	iounmap(mpsoc_base);
+	of_node_put(np);
+
+	/* Set up delay */
+	reg = readl(pmsu_mp_base + PMSU_POWERDOWN_DELAY);
+	reg &= ~PMSU_POWERDOWN_DELAY_MASK;
+	reg |= PMSU_DFLT_ARMADA38X_DELAY;
+	reg |= PMSU_POWERDOWN_DELAY_PMU;
+	writel(reg, pmsu_mp_base + PMSU_POWERDOWN_DELAY);
+
+	scu_base = mvebu_get_scu_base();
+	mvebu_cpu_resume = armada_38x_cpu_resume;
+	mvebu_v7_cpuidle_device.dev.platform_data = &armada_38x_cpuidle;
+	return true;
+}
+
 static __init bool armada_xp_cpuidle_init(void)
 {
 	struct device_node *np;
@@ -391,6 +485,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
 	{ .compatible = "marvell,armada370",
 	  .data = (void *)armada_370_cpuidle_init,
 	},
+	{ .compatible = "marvell,armada380",
+	  .data = (void *)armada_38x_cpuidle_init,
+	},
 	{ /* end of list */ },
 };
 
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index 3b702a16bd3d..15b823dff61a 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -23,6 +23,20 @@ ARM_BE8(setend	be )			@ go BE8 if entered LE
 	b	cpu_resume
 ENDPROC(armada_370_xp_cpu_resume)
 
+ENTRY(armada_38x_cpu_resume)
+	/* do we need it for Armada 38x*/
+ARM_BE8(setend	be )			@ go BE8 if entered LE
+	bl	v7_invalidate_l1
+	mrc     p15, 4, r1, c15, c0	@ get SCU base address
+	orr	r1, r1, #0x8		@ SCU CPU Power Status Register
+	mrc	15, 0, r0, cr0, cr0, 5	@ get the CPU ID
+	and	r0, r0, #15
+	add	r1, r1, r0
+	mov	r0, #0x0
+	strb	r0, [r1]		@ switch SCU power state to Normal mode
+	b	cpu_resume
+ENDPROC(armada_38x_cpu_resume)
+
 .global mvebu_boot_wa_start
 .global mvebu_boot_wa_end
 
-- 
1.8.1.2


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

* [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

Unlike the Armada XP and the Armada 370, this SoC uses a Cortex A9
core. Beside this, the main difference for the cpu idle is the way to
handle the L2 cache and the use of SCU.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/mach-mvebu/pmsu.c    | 101 +++++++++++++++++++++++++++++++++++++++++-
 arch/arm/mach-mvebu/pmsu_ll.S |  14 ++++++
 2 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index bfd471538811..3e49fb73c3d5 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -32,6 +32,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cpuidle.h>
 #include <asm/cp15.h>
+#include <asm/smp_scu.h>
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
@@ -66,6 +67,19 @@
 #define L2C_NFABRIC_PM_CTL		    0x4
 #define L2C_NFABRIC_PM_CTL_PWR_DOWN		BIT(20)
 
+/* PMSU delay registers */
+#define PMSU_POWERDOWN_DELAY		    0xF04
+#define PMSU_POWERDOWN_DELAY_PMU		BIT(1)
+#define PMSU_POWERDOWN_DELAY_MASK		0xFFFE
+
+#define PMSU_DFLT_ARMADA38X_DELAY	0x64
+
+/* CA9 MPcore SoC Control registers */
+
+#define MPCORE_RESET_CTL		    0x64
+#define MPCORE_RESET_CTL_L2			BIT(0)
+#define MPCORE_RESET_CTL_DEBUG			BIT(16)
+
 #define ARMADA_370_CRYPT0_ENG_ID	0x9
 #define CRYPT0_ENG_ATTR	0x1
 
@@ -78,10 +92,13 @@ extern void ll_disable_coherency(void);
 extern void ll_enable_coherency(void);
 
 extern void armada_370_xp_cpu_resume(void);
+extern void armada_38x_cpu_resume(void);
 
 static unsigned long pmsu_mp_phys_base;
 static void __iomem *pmsu_mp_base;
 
+static void __iomem *scu_base;
+
 static void *mvebu_cpu_resume;
 
 static struct platform_device mvebu_v7_cpuidle_device = {
@@ -151,6 +168,7 @@ static int __init mvebu_v7_pmsu_init(void)
 				np->full_name)) {
 		pr_err("unable to request region\n");
 		ret = -EBUSY;
+
 		goto out;
 	}
 
@@ -163,7 +181,6 @@ static int __init mvebu_v7_pmsu_init(void)
 		ret = -ENOMEM;
 		goto out;
 	}
-
  out:
 	of_node_put(np);
 	return ret;
@@ -260,6 +277,27 @@ static int armada_xp_370_cpu_suspend(unsigned long deepidle)
 	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
 }
 
+static noinline int do_armada_38x_cpu_suspend(unsigned long deepidle)
+{
+	mvebu_v7_pmsu_idle_prepare(deepidle, false);
+	/*
+	 * Already flushed cache, but do it again as the outer cache
+	 * functions dirty the cache with spinlocks
+	 */
+	v7_exit_coherency_flush(louis);
+
+	scu_power_mode(scu_base, SCU_PM_POWEROFF);
+
+	cpu_do_idle();
+
+	return 1;
+}
+
+static int armada_38x_cpu_suspend(unsigned long deepidle)
+{
+	return cpu_suspend(false, do_armada_38x_cpu_suspend);
+}
+
 /* No locking is needed because we only access per-CPU registers */
 static noinline void mvebu_v7_pmsu_idle_restore(void)
 {
@@ -268,7 +306,6 @@ static noinline void mvebu_v7_pmsu_idle_restore(void)
 
 	if (pmsu_mp_base == NULL)
 		return;
-
 	/* cancel ask HW to power down the L2 Cache if possible */
 	reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
 	reg &= ~PMSU_CONTROL_AND_CONFIG_L2_PWDDN;
@@ -320,6 +357,23 @@ static struct mvebu_v7_cpuidle armada_370_cpuidle = {
 	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
 };
 
+static struct mvebu_v7_cpuidle armada_38x_cpuidle = {
+	.mvebu_v7_idle_driver = {
+		.name			= "armada_38x_idle",
+		.states[0]		= ARM_CPUIDLE_WFI_STATE,
+		.states[1]		= {
+			.exit_latency		= 10,
+			.power_usage		= 5,
+			.target_residency	= 100,
+			.flags			= CPUIDLE_FLAG_TIME_VALID,
+			.name			= "Idle",
+			.desc			= "CPU and SCU power down",
+		},
+		.state_count = 2,
+	},
+	.mvebu_v7_cpu_suspend = armada_38x_cpu_suspend,
+};
+
 static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
 	.mvebu_v7_idle_driver = {
 		.name			= "armada_xp_idle",
@@ -371,6 +425,46 @@ static __init bool armada_370_cpuidle_init(void)
 	return true;
 }
 
+static __init bool armada_38x_cpuidle_init(void)
+{
+	struct device_node *np;
+	void __iomem *mpsoc_base;
+	u32 reg;
+
+	np = of_find_compatible_node(NULL, NULL,
+				"marvell,armada-380-coherency-fabric");
+	if (!np)
+		return false;
+	of_node_put(np);
+
+	np = of_find_compatible_node(NULL, NULL,
+				"marvell,armada-380-mpcore-soc-ctrl");
+	if (!np)
+		return false;
+	mpsoc_base = of_iomap(np, 0);
+	WARN_ON(!mpsoc_base);
+
+	/* Set up reset mask when powering down the cpus */
+	reg = readl(mpsoc_base + MPCORE_RESET_CTL);
+	reg |= MPCORE_RESET_CTL_L2;
+	reg |= MPCORE_RESET_CTL_DEBUG;
+	writel(reg, mpsoc_base + MPCORE_RESET_CTL);
+	iounmap(mpsoc_base);
+	of_node_put(np);
+
+	/* Set up delay */
+	reg = readl(pmsu_mp_base + PMSU_POWERDOWN_DELAY);
+	reg &= ~PMSU_POWERDOWN_DELAY_MASK;
+	reg |= PMSU_DFLT_ARMADA38X_DELAY;
+	reg |= PMSU_POWERDOWN_DELAY_PMU;
+	writel(reg, pmsu_mp_base + PMSU_POWERDOWN_DELAY);
+
+	scu_base = mvebu_get_scu_base();
+	mvebu_cpu_resume = armada_38x_cpu_resume;
+	mvebu_v7_cpuidle_device.dev.platform_data = &armada_38x_cpuidle;
+	return true;
+}
+
 static __init bool armada_xp_cpuidle_init(void)
 {
 	struct device_node *np;
@@ -391,6 +485,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
 	{ .compatible = "marvell,armada370",
 	  .data = (void *)armada_370_cpuidle_init,
 	},
+	{ .compatible = "marvell,armada380",
+	  .data = (void *)armada_38x_cpuidle_init,
+	},
 	{ /* end of list */ },
 };
 
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index 3b702a16bd3d..15b823dff61a 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -23,6 +23,20 @@ ARM_BE8(setend	be )			@ go BE8 if entered LE
 	b	cpu_resume
 ENDPROC(armada_370_xp_cpu_resume)
 
+ENTRY(armada_38x_cpu_resume)
+	/* do we need it for Armada 38x*/
+ARM_BE8(setend	be )			@ go BE8 if entered LE
+	bl	v7_invalidate_l1
+	mrc     p15, 4, r1, c15, c0	@ get SCU base address
+	orr	r1, r1, #0x8		@ SCU CPU Power Status Register
+	mrc	15, 0, r0, cr0, cr0, 5	@ get the CPU ID
+	and	r0, r0, #15
+	add	r1, r1, r0
+	mov	r0, #0x0
+	strb	r0, [r1]		@ switch SCU power state to Normal mode
+	b	cpu_resume
+ENDPROC(armada_38x_cpu_resume)
+
 .global mvebu_boot_wa_start
 .global mvebu_boot_wa_end
 
-- 
1.8.1.2

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

* [PATCH 16/16] ARM: mvebu: defconfig: Enable CPU Idle support in mvebu_v7_defconfig
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-27 13:22   ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

mvebu SoCs such as Armada 370, Armada XP or Armada 38x now support CPU
Idle so let's add it in the default configuration.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/configs/mvebu_v7_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index e11170e37442..b174072cabd8 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -28,6 +28,8 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_MVEBU_V7_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NET=y
 CONFIG_INET=y
-- 
1.8.1.2


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

* [PATCH 16/16] ARM: mvebu: defconfig: Enable CPU Idle support in mvebu_v7_defconfig
@ 2014-06-27 13:22   ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 13:22 UTC (permalink / raw)
  To: linux-arm-kernel

mvebu SoCs such as Armada 370, Armada XP or Armada 38x now support CPU
Idle so let's add it in the default configuration.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
 arch/arm/configs/mvebu_v7_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index e11170e37442..b174072cabd8 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -28,6 +28,8 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_MVEBU_V7_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NET=y
 CONFIG_INET=y
-- 
1.8.1.2

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

* Re: [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-27 14:14     ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 14:14 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

On 27/06/2014 15:22, Gregory CLEMENT wrote:
> In order to boot the secondary CPUs on Armada 375 Z1, we need to read
> the boot address of these CPUs through a register part of the System
> Controller. This done very early where MMU is not enable yet, so we
> need to get the physical address of this register to use it.
> 
> In the previous version of this workaround the physical address were
> hardcoded whereas depending of the Mbus configuration this address may
> change.
> 
> This commit will allow to use the generic boot workaround function
> with the correct address.

I forgot my signed-off here
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

> ---
>  arch/arm/mach-mvebu/common.h            |  1 +
>  arch/arm/mach-mvebu/system-controller.c | 11 +++++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
> index b67fb7a10d8b..6ad62cf8352c 100644
> --- a/arch/arm/mach-mvebu/common.h
> +++ b/arch/arm/mach-mvebu/common.h
> @@ -20,6 +20,7 @@
>  void mvebu_restart(enum reboot_mode mode, const char *cmd);
>  int mvebu_cpu_reset_deassert(int cpu);
>  void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
> +u32 mvebu_system_controller_get_phys_addr(void);
>  void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
>  
>  void armada_xp_cpu_die(unsigned int cpu);
> diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
> index 0c5524ac75b7..ae6ab543aa36 100644
> --- a/arch/arm/mach-mvebu/system-controller.c
> +++ b/arch/arm/mach-mvebu/system-controller.c
> @@ -30,6 +30,7 @@
>  #include "common.h"
>  
>  static void __iomem *system_controller_base;
> +static u32 system_controller_phys_base;
>  
>  struct mvebu_system_controller {
>  	u32 rstoutn_mask_offset;
> @@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
>  	writel(virt_to_phys(boot_addr), system_controller_base +
>  	       mvebu_sc->resume_boot_addr);
>  }
> +
> +u32 mvebu_system_controller_get_phys_addr(void)
> +{
> +	BUG_ON(system_controller_phys_base == NULL);
> +	BUG_ON(mvebu_sc->resume_boot_addr == 0);
> +	return system_controller_phys_base + mvebu_sc->resume_boot_addr;
> +}
>  #endif
>  
>  static int __init mvebu_system_controller_init(void)
> @@ -119,7 +127,10 @@ static int __init mvebu_system_controller_init(void)
>  	np = of_find_matching_node_and_match(NULL, of_system_controller_table,
>  					     &match);
>  	if (np) {
> +		struct resource res;
>  		system_controller_base = of_iomap(np, 0);
> +		of_address_to_resource(np, 0, &res);
> +		system_controller_phys_base = res.start;
>  		mvebu_sc = (struct mvebu_system_controller *)match->data;
>  		of_node_put(np);
>  	}
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
@ 2014-06-27 14:14     ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 27/06/2014 15:22, Gregory CLEMENT wrote:
> In order to boot the secondary CPUs on Armada 375 Z1, we need to read
> the boot address of these CPUs through a register part of the System
> Controller. This done very early where MMU is not enable yet, so we
> need to get the physical address of this register to use it.
> 
> In the previous version of this workaround the physical address were
> hardcoded whereas depending of the Mbus configuration this address may
> change.
> 
> This commit will allow to use the generic boot workaround function
> with the correct address.

I forgot my signed-off here
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

> ---
>  arch/arm/mach-mvebu/common.h            |  1 +
>  arch/arm/mach-mvebu/system-controller.c | 11 +++++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
> index b67fb7a10d8b..6ad62cf8352c 100644
> --- a/arch/arm/mach-mvebu/common.h
> +++ b/arch/arm/mach-mvebu/common.h
> @@ -20,6 +20,7 @@
>  void mvebu_restart(enum reboot_mode mode, const char *cmd);
>  int mvebu_cpu_reset_deassert(int cpu);
>  void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
> +u32 mvebu_system_controller_get_phys_addr(void);
>  void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
>  
>  void armada_xp_cpu_die(unsigned int cpu);
> diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
> index 0c5524ac75b7..ae6ab543aa36 100644
> --- a/arch/arm/mach-mvebu/system-controller.c
> +++ b/arch/arm/mach-mvebu/system-controller.c
> @@ -30,6 +30,7 @@
>  #include "common.h"
>  
>  static void __iomem *system_controller_base;
> +static u32 system_controller_phys_base;
>  
>  struct mvebu_system_controller {
>  	u32 rstoutn_mask_offset;
> @@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
>  	writel(virt_to_phys(boot_addr), system_controller_base +
>  	       mvebu_sc->resume_boot_addr);
>  }
> +
> +u32 mvebu_system_controller_get_phys_addr(void)
> +{
> +	BUG_ON(system_controller_phys_base == NULL);
> +	BUG_ON(mvebu_sc->resume_boot_addr == 0);
> +	return system_controller_phys_base + mvebu_sc->resume_boot_addr;
> +}
>  #endif
>  
>  static int __init mvebu_system_controller_init(void)
> @@ -119,7 +127,10 @@ static int __init mvebu_system_controller_init(void)
>  	np = of_find_matching_node_and_match(NULL, of_system_controller_table,
>  					     &match);
>  	if (np) {
> +		struct resource res;
>  		system_controller_base = of_iomap(np, 0);
> +		of_address_to_resource(np, 0, &res);
> +		system_controller_phys_base = res.start;
>  		mvebu_sc = (struct mvebu_system_controller *)match->data;
>  		of_node_put(np);
>  	}
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-27 14:15     ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 14:15 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Gregory CLEMENT
  Cc: Thomas Petazzoni, Ezequiel Garcia, linux-arm-kernel,
	Lior Amsalem, Tawfik Bayouk, Nadav Haklai

On 27/06/2014 15:22, Gregory CLEMENT wrote:
> In order to support more mvebu SoCs, this patch use an initialization
> specific function associated to each SoCs which support CPU Idle.
> 
> Then each SoC will have his own set of check and of data
> configuration.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++--------
>  1 file changed, 31 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index 087157c20b8a..454f0f9ede6b 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -293,23 +293,47 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
>  	.notifier_call = mvebu_v7_cpu_pm_notify,
>  };
>  
> +static bool (*mvebu_v7_cpu_idle_init)(void);
> +
> +static __init bool armada_xp_cpuidle_init(void)
> +{
> +	struct device_node *np;
> +
> +	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> +	if (!np)
> +		return false;
> +	of_node_put(np);
> +
> +	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
> +	return true;
> +}
> +
> +static struct of_device_id of_cpuidle_table[] __initdata = {
> +	{ .compatible = "marvell,armadaxp",
> +	  .data = (void *)armada_xp_cpuidle_init,
> +	},
> +	{ /* end of list */ },
> +};
> +
>  static int __init mvebu_v7_cpu_pm_init(void)
>  {
>  	struct device_node *np;
> +	const struct of_device_id *match;
> +
> +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
> +					&match);
> +

The following part was missing (without this the kernel hang on Armada 375)

+       if (!np)
+               return 0;



>  
>  	/*
>  	 * Check that all the requirements are available to enable
> -	 * cpuidle. So far, it is only supported on Armada XP, cpuidle
> -	 * needs the coherency fabric and the PMSU enabled
> +	 * cpuidle. Each SoCs comes with its own requirements and
> +	 * configuration
>  	 */
>  
> -	if (!of_machine_is_compatible("marvell,armadaxp"))
> -		return 0;
> +	mvebu_v7_cpu_idle_init = (bool (*)(void))match->data;
>  
> -	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> -	if (!np)
> +	if (!mvebu_v7_cpu_idle_init())
>  		return 0;
> -	of_node_put(np);
>  
>  	np = of_find_matching_node(NULL, of_pmsu_table);
>  	if (!np)
> @@ -329,7 +353,6 @@ static int __init mvebu_v7_cpu_pm_init(void)
>  				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
>  
>  	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
> -	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
>  	platform_device_register(&mvebu_v7_cpuidle_device);
>  	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
>  
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
@ 2014-06-27 14:15     ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-27 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 27/06/2014 15:22, Gregory CLEMENT wrote:
> In order to support more mvebu SoCs, this patch use an initialization
> specific function associated to each SoCs which support CPU Idle.
> 
> Then each SoC will have his own set of check and of data
> configuration.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++--------
>  1 file changed, 31 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index 087157c20b8a..454f0f9ede6b 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -293,23 +293,47 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
>  	.notifier_call = mvebu_v7_cpu_pm_notify,
>  };
>  
> +static bool (*mvebu_v7_cpu_idle_init)(void);
> +
> +static __init bool armada_xp_cpuidle_init(void)
> +{
> +	struct device_node *np;
> +
> +	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> +	if (!np)
> +		return false;
> +	of_node_put(np);
> +
> +	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
> +	return true;
> +}
> +
> +static struct of_device_id of_cpuidle_table[] __initdata = {
> +	{ .compatible = "marvell,armadaxp",
> +	  .data = (void *)armada_xp_cpuidle_init,
> +	},
> +	{ /* end of list */ },
> +};
> +
>  static int __init mvebu_v7_cpu_pm_init(void)
>  {
>  	struct device_node *np;
> +	const struct of_device_id *match;
> +
> +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
> +					&match);
> +

The following part was missing (without this the kernel hang on Armada 375)

+       if (!np)
+               return 0;



>  
>  	/*
>  	 * Check that all the requirements are available to enable
> -	 * cpuidle. So far, it is only supported on Armada XP, cpuidle
> -	 * needs the coherency fabric and the PMSU enabled
> +	 * cpuidle. Each SoCs comes with its own requirements and
> +	 * configuration
>  	 */
>  
> -	if (!of_machine_is_compatible("marvell,armadaxp"))
> -		return 0;
> +	mvebu_v7_cpu_idle_init = (bool (*)(void))match->data;
>  
> -	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> -	if (!np)
> +	if (!mvebu_v7_cpu_idle_init())
>  		return 0;
> -	of_node_put(np);
>  
>  	np = of_find_matching_node(NULL, of_pmsu_table);
>  	if (!np)
> @@ -329,7 +353,6 @@ static int __init mvebu_v7_cpu_pm_init(void)
>  				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
>  
>  	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
> -	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
>  	platform_device_register(&mvebu_v7_cpuidle_device);
>  	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);
>  
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
  2014-06-27 14:15     ` Gregory CLEMENT
@ 2014-06-28 14:56       ` Jason Cooper
  -1 siblings, 0 replies; 120+ messages in thread
From: Jason Cooper @ 2014-06-28 14:56 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Andrew Lunn,
	Sebastian Hesselbarth, Thomas Petazzoni, Ezequiel Garcia,
	linux-arm-kernel, Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Gregory,

On Fri, Jun 27, 2014 at 04:15:44PM +0200, Gregory CLEMENT wrote:
> On 27/06/2014 15:22, Gregory CLEMENT wrote:
> > In order to support more mvebu SoCs, this patch use an initialization
> > specific function associated to each SoCs which support CPU Idle.
> > 
> > Then each SoC will have his own set of check and of data
> > configuration.
> > 
> > Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> > ---
> >  arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++--------
> >  1 file changed, 31 insertions(+), 8 deletions(-)
> > 
> > diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> > index 087157c20b8a..454f0f9ede6b 100644
> > --- a/arch/arm/mach-mvebu/pmsu.c
> > +++ b/arch/arm/mach-mvebu/pmsu.c
> > @@ -293,23 +293,47 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
> >  	.notifier_call = mvebu_v7_cpu_pm_notify,
> >  };
> >  
> > +static bool (*mvebu_v7_cpu_idle_init)(void);
> > +
> > +static __init bool armada_xp_cpuidle_init(void)
> > +{
> > +	struct device_node *np;
> > +
> > +	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> > +	if (!np)
> > +		return false;
> > +	of_node_put(np);
> > +
> > +	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
> > +	return true;
> > +}
> > +
> > +static struct of_device_id of_cpuidle_table[] __initdata = {
> > +	{ .compatible = "marvell,armadaxp",
> > +	  .data = (void *)armada_xp_cpuidle_init,
> > +	},
> > +	{ /* end of list */ },
> > +};
> > +
> >  static int __init mvebu_v7_cpu_pm_init(void)
> >  {
> >  	struct device_node *np;
> > +	const struct of_device_id *match;
> > +
> > +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
> > +					&match);
> > +
> 
> The following part was missing (without this the kernel hang on Armada 375)
> 
> +       if (!np)
> +               return 0;

If there's no other changes, I can fix this up when I apply it.  As well
as the S-o-b.

thx,

Jason.

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

* [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
@ 2014-06-28 14:56       ` Jason Cooper
  0 siblings, 0 replies; 120+ messages in thread
From: Jason Cooper @ 2014-06-28 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, Jun 27, 2014 at 04:15:44PM +0200, Gregory CLEMENT wrote:
> On 27/06/2014 15:22, Gregory CLEMENT wrote:
> > In order to support more mvebu SoCs, this patch use an initialization
> > specific function associated to each SoCs which support CPU Idle.
> > 
> > Then each SoC will have his own set of check and of data
> > configuration.
> > 
> > Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> > ---
> >  arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++--------
> >  1 file changed, 31 insertions(+), 8 deletions(-)
> > 
> > diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> > index 087157c20b8a..454f0f9ede6b 100644
> > --- a/arch/arm/mach-mvebu/pmsu.c
> > +++ b/arch/arm/mach-mvebu/pmsu.c
> > @@ -293,23 +293,47 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
> >  	.notifier_call = mvebu_v7_cpu_pm_notify,
> >  };
> >  
> > +static bool (*mvebu_v7_cpu_idle_init)(void);
> > +
> > +static __init bool armada_xp_cpuidle_init(void)
> > +{
> > +	struct device_node *np;
> > +
> > +	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> > +	if (!np)
> > +		return false;
> > +	of_node_put(np);
> > +
> > +	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
> > +	return true;
> > +}
> > +
> > +static struct of_device_id of_cpuidle_table[] __initdata = {
> > +	{ .compatible = "marvell,armadaxp",
> > +	  .data = (void *)armada_xp_cpuidle_init,
> > +	},
> > +	{ /* end of list */ },
> > +};
> > +
> >  static int __init mvebu_v7_cpu_pm_init(void)
> >  {
> >  	struct device_node *np;
> > +	const struct of_device_id *match;
> > +
> > +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
> > +					&match);
> > +
> 
> The following part was missing (without this the kernel hang on Armada 375)
> 
> +       if (!np)
> +               return 0;

If there's no other changes, I can fix this up when I apply it.  As well
as the S-o-b.

thx,

Jason.

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

* Re: [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
  2014-06-28 14:56       ` Jason Cooper
@ 2014-06-30 10:30         ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-30 10:30 UTC (permalink / raw)
  To: Jason Cooper
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Andrew Lunn,
	Sebastian Hesselbarth, Thomas Petazzoni, Ezequiel Garcia,
	linux-arm-kernel, Lior Amsalem, Tawfik Bayouk, Nadav Haklai

Hi Jason,


>>> +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
>>> +					&match);
>>> +
>>
>> The following part was missing (without this the kernel hang on Armada 375)
>>
>> +       if (!np)
>> +               return 0;
> 
> If there's no other changes, I can fix this up when I apply it.  As well
> as the S-o-b.


Thanks. Let's hope it will be the case, and there will no need to a
new version of this series. :)

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
@ 2014-06-30 10:30         ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-30 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jason,


>>> +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
>>> +					&match);
>>> +
>>
>> The following part was missing (without this the kernel hang on Armada 375)
>>
>> +       if (!np)
>> +               return 0;
> 
> If there's no other changes, I can fix this up when I apply it.  As well
> as the S-o-b.


Thanks. Let's hope it will be the case, and there will no need to a
new version of this series. :)

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 01/16] ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 12:16     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:16 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:42 +0200, Gregory CLEMENT wrote:
> Sorting the headers in alphabetic order will help to reduce the
> conflict when adding new headers later.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index a1d407c0febe..5584d35b8e88 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -19,13 +19,13 @@
>  #define pr_fmt(fmt) "mvebu-pmsu: " fmt
>  
>  #include <linux/cpu_pm.h>
> -#include <linux/kernel.h>
>  #include <linux/init.h>
> -#include <linux/of_address.h>
> +#include <linux/kernel.h>
>  #include <linux/io.h>

So, with your patch applied, if I'm correct, we will have:

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>

It seems like we're not yet alphabetically sorted here :)

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 01/16] ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
@ 2014-06-30 12:16     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:16 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:42 +0200, Gregory CLEMENT wrote:
> Sorting the headers in alphabetic order will help to reduce the
> conflict when adding new headers later.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index a1d407c0febe..5584d35b8e88 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -19,13 +19,13 @@
>  #define pr_fmt(fmt) "mvebu-pmsu: " fmt
>  
>  #include <linux/cpu_pm.h>
> -#include <linux/kernel.h>
>  #include <linux/init.h>
> -#include <linux/of_address.h>
> +#include <linux/kernel.h>
>  #include <linux/io.h>

So, with your patch applied, if I'm correct, we will have:

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>

It seems like we're not yet alphabetically sorted here :)

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 12:40     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:40 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:43 +0200, Gregory CLEMENT wrote:

> On some of the mvebu SoC and due to internal bootrom issue, CPU

"due to an internal BootROM issue, the CPU"

> initial jump code should be placed in SRAM memory of the SoC. In order

"in SRAM memory" -> "in the SRAM memory".

> to achieve this, we have to unmap the BootROM and at some specific
> location where the BootROM was place, create a specific MBus window

place -> placed

> for the SRAM. This SRAM is initialized with a few instructions of code
> that allows to jump into the real secondary CPU boot address.

jump into -> jump to.

> This work around currently needed for booting SMP on Aramda 375 Z1 and

This work around *is* currently needed for SMP support on *Armada*.

> will be needed for cpuidle support on Armada 370. Instead of duplicate

duplicate -> duplicating.

> the same code, this commit introduce a common function to handle it:

introduce -> introduces.

> mvebu_boot_addr_wa().

I'm not sure the name of the function is appropriate, as we don't know
what it is doing. Maybe mvebu_setup_boot_addr_wa() ?

Also, maybe your commit log should indicate that the workaround
involves using the Crypto engine SRAM, which will help understanding
the reference to the crypto engine in the code.

> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c    | 31 +++++++++++++++++++++++++++++++
>  arch/arm/mach-mvebu/pmsu.h    |  1 +
>  arch/arm/mach-mvebu/pmsu_ll.S | 19 +++++++++++++++++++
>  3 files changed, 51 insertions(+)

I don't really have a better suggestion, but the workaround doesn't
seem to be related to the PMSU, so are pmsu.c and pmsu_ll.S really the
right files to store this code?

> 
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index 5584d35b8e88..991560905ccc 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -22,6 +22,7 @@
>  #include <linux/init.h>
>  #include <linux/kernel.h>
>  #include <linux/io.h>
> +#include <linux/mbus.h>
>  #include <linux/of_address.h>
>  #include <linux/platform_device.h>
>  #include <linux/resource.h>
> @@ -63,6 +64,14 @@ static void __iomem *pmsu_mp_base;
>  #define L2C_NFABRIC_PM_CTL		    0x4
>  #define L2C_NFABRIC_PM_CTL_PWR_DOWN		BIT(20)
>  
> +#define ARMADA_370_CRYPT0_ENG_ID	0x9

Not needed in this file, the MBus window target ID is passed as
argument to the mvebu_boot_addr_wa() function.

> +#define CRYPT0_ENG_ATTR	0x1

For consistency, I'd prefer to see this being passed as argument to
mvebu_boot_addr_wa().

> +#define SRAM_PHYS_BASE	    0xFFFF0000
> +
> +#define BOOTROM_BASE    0xFFF00000
> +#define BOOTROM_SIZE    0x100000
> +
>  extern void ll_disable_coherency(void);
>  extern void ll_enable_coherency(void);
>  
> @@ -85,6 +94,28 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
>  		PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
>  }
>  
> +extern unsigned char mvebu_boot_wa_start;
> +extern unsigned char mvebu_boot_wa_end;
> +
> +void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)

unsigned int crypto_eng_target ('unsigned int' is the type used by
the mvebu-mbus API), and add unsigned int crypto_eng_attribute, to
match the mvebu-mbus API. Also, void * seems more appropriate than u32
for an address, maybe even void __iomem * since it's actually pointing
to a memory-mapped register.

> +{
> +	void __iomem *sram_virt_base;
> +	u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
> +
> +	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
> +	mvebu_mbus_add_window_by_id(crypto_eng_id, CRYPT0_ENG_ATTR,
> +				SRAM_PHYS_BASE, SZ_64K);
> +	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);

Maybe a return value check?

> +
> +

One too many new line.

> +	memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
> +	/*
> +	 * The last word of the code copied in SRAM must contain the
> +	 * physical base address of the PMSU register
> +	 */
> +	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;

Maybe instead:

	writel(resume_addr_reg, sram_virt_base + code_len - 4);

And also:

	iounmap(sram_virt_base);

> +}
> +
>  static int __init armada_370_xp_pmsu_init(void)
>  {
>  	struct device_node *np;
> diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h
> index 07a737c6b95d..2d97a70c2558 100644
> --- a/arch/arm/mach-mvebu/pmsu.h
> +++ b/arch/arm/mach-mvebu/pmsu.h
> @@ -12,5 +12,6 @@
>  #define __MACH_MVEBU_PMSU_H
>  
>  int armada_xp_boot_cpu(unsigned int cpu_id, void *phys_addr);
> +void mvebu_boot_addr_wa(int crypto_eng_id, unsigned long resume_addr_reg);
>  
>  #endif	/* __MACH_370_XP_PMSU_H */
> diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
> index fc3de68d8c54..3b702a16bd3d 100644
> --- a/arch/arm/mach-mvebu/pmsu_ll.S
> +++ b/arch/arm/mach-mvebu/pmsu_ll.S
> @@ -23,3 +23,22 @@ ARM_BE8(setend	be )			@ go BE8 if entered LE
>  	b	cpu_resume
>  ENDPROC(armada_370_xp_cpu_resume)
>  
> +.global mvebu_boot_wa_start
> +.global mvebu_boot_wa_end
> +
> +/* The following code will be executed from SRAM */
> +ENTRY(mvebu_boot_wa_start)
> +mvebu_boot_wa_start:
> +/* use physical address of the boot address register register */

"register register" -> register.

> +	adr     r0, 1f
> +	ldr     r0, [r0]
> +	ldr     r0, [r0]
> +	mov     pc, r0
> +/*
> + * the last word of this piece of code will be filled by the physical

"filled with". "filled by" indicates *who* is filling the missing
information, "filled with" indicates with *what* it is being filled.

> + * address of the boot address register just after being copied in SRAM
> + */
> +1:
> +	.long   .
> +mvebu_boot_wa_end:
> +ENDPROC(mvebu_boot_wa_end)

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
@ 2014-06-30 12:40     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:43 +0200, Gregory CLEMENT wrote:

> On some of the mvebu SoC and due to internal bootrom issue, CPU

"due to an internal BootROM issue, the CPU"

> initial jump code should be placed in SRAM memory of the SoC. In order

"in SRAM memory" -> "in the SRAM memory".

> to achieve this, we have to unmap the BootROM and at some specific
> location where the BootROM was place, create a specific MBus window

place -> placed

> for the SRAM. This SRAM is initialized with a few instructions of code
> that allows to jump into the real secondary CPU boot address.

jump into -> jump to.

> This work around currently needed for booting SMP on Aramda 375 Z1 and

This work around *is* currently needed for SMP support on *Armada*.

> will be needed for cpuidle support on Armada 370. Instead of duplicate

duplicate -> duplicating.

> the same code, this commit introduce a common function to handle it:

introduce -> introduces.

> mvebu_boot_addr_wa().

I'm not sure the name of the function is appropriate, as we don't know
what it is doing. Maybe mvebu_setup_boot_addr_wa() ?

Also, maybe your commit log should indicate that the workaround
involves using the Crypto engine SRAM, which will help understanding
the reference to the crypto engine in the code.

> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c    | 31 +++++++++++++++++++++++++++++++
>  arch/arm/mach-mvebu/pmsu.h    |  1 +
>  arch/arm/mach-mvebu/pmsu_ll.S | 19 +++++++++++++++++++
>  3 files changed, 51 insertions(+)

I don't really have a better suggestion, but the workaround doesn't
seem to be related to the PMSU, so are pmsu.c and pmsu_ll.S really the
right files to store this code?

> 
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index 5584d35b8e88..991560905ccc 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -22,6 +22,7 @@
>  #include <linux/init.h>
>  #include <linux/kernel.h>
>  #include <linux/io.h>
> +#include <linux/mbus.h>
>  #include <linux/of_address.h>
>  #include <linux/platform_device.h>
>  #include <linux/resource.h>
> @@ -63,6 +64,14 @@ static void __iomem *pmsu_mp_base;
>  #define L2C_NFABRIC_PM_CTL		    0x4
>  #define L2C_NFABRIC_PM_CTL_PWR_DOWN		BIT(20)
>  
> +#define ARMADA_370_CRYPT0_ENG_ID	0x9

Not needed in this file, the MBus window target ID is passed as
argument to the mvebu_boot_addr_wa() function.

> +#define CRYPT0_ENG_ATTR	0x1

For consistency, I'd prefer to see this being passed as argument to
mvebu_boot_addr_wa().

> +#define SRAM_PHYS_BASE	    0xFFFF0000
> +
> +#define BOOTROM_BASE    0xFFF00000
> +#define BOOTROM_SIZE    0x100000
> +
>  extern void ll_disable_coherency(void);
>  extern void ll_enable_coherency(void);
>  
> @@ -85,6 +94,28 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
>  		PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
>  }
>  
> +extern unsigned char mvebu_boot_wa_start;
> +extern unsigned char mvebu_boot_wa_end;
> +
> +void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)

unsigned int crypto_eng_target ('unsigned int' is the type used by
the mvebu-mbus API), and add unsigned int crypto_eng_attribute, to
match the mvebu-mbus API. Also, void * seems more appropriate than u32
for an address, maybe even void __iomem * since it's actually pointing
to a memory-mapped register.

> +{
> +	void __iomem *sram_virt_base;
> +	u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
> +
> +	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
> +	mvebu_mbus_add_window_by_id(crypto_eng_id, CRYPT0_ENG_ATTR,
> +				SRAM_PHYS_BASE, SZ_64K);
> +	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);

Maybe a return value check?

> +
> +

One too many new line.

> +	memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
> +	/*
> +	 * The last word of the code copied in SRAM must contain the
> +	 * physical base address of the PMSU register
> +	 */
> +	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;

Maybe instead:

	writel(resume_addr_reg, sram_virt_base + code_len - 4);

And also:

	iounmap(sram_virt_base);

> +}
> +
>  static int __init armada_370_xp_pmsu_init(void)
>  {
>  	struct device_node *np;
> diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h
> index 07a737c6b95d..2d97a70c2558 100644
> --- a/arch/arm/mach-mvebu/pmsu.h
> +++ b/arch/arm/mach-mvebu/pmsu.h
> @@ -12,5 +12,6 @@
>  #define __MACH_MVEBU_PMSU_H
>  
>  int armada_xp_boot_cpu(unsigned int cpu_id, void *phys_addr);
> +void mvebu_boot_addr_wa(int crypto_eng_id, unsigned long resume_addr_reg);
>  
>  #endif	/* __MACH_370_XP_PMSU_H */
> diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
> index fc3de68d8c54..3b702a16bd3d 100644
> --- a/arch/arm/mach-mvebu/pmsu_ll.S
> +++ b/arch/arm/mach-mvebu/pmsu_ll.S
> @@ -23,3 +23,22 @@ ARM_BE8(setend	be )			@ go BE8 if entered LE
>  	b	cpu_resume
>  ENDPROC(armada_370_xp_cpu_resume)
>  
> +.global mvebu_boot_wa_start
> +.global mvebu_boot_wa_end
> +
> +/* The following code will be executed from SRAM */
> +ENTRY(mvebu_boot_wa_start)
> +mvebu_boot_wa_start:
> +/* use physical address of the boot address register register */

"register register" -> register.

> +	adr     r0, 1f
> +	ldr     r0, [r0]
> +	ldr     r0, [r0]
> +	mov     pc, r0
> +/*
> + * the last word of this piece of code will be filled by the physical

"filled with". "filled by" indicates *who* is filling the missing
information, "filled with" indicates with *what* it is being filled.

> + * address of the boot address register just after being copied in SRAM
> + */
> +1:
> +	.long   .
> +mvebu_boot_wa_end:
> +ENDPROC(mvebu_boot_wa_end)

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 12:46     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:46 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

I'm not sure that the best approach to solve this problem. Instead,
maybe the system-controller.c code should set up the boot address
workaround on Armada 375. Since the workaround on 375 is really related
to setting the boot address which is done by the system controller,
maybe the initialization of the workaround belongs in
system-controller.c ?

On Fri, 27 Jun 2014 15:22:44 +0200, Gregory CLEMENT wrote:
> In order to boot the secondary CPUs on Armada 375 Z1, we need to read
> the boot address of these CPUs through a register part of the System
> Controller. This done very early where MMU is not enable yet, so we
> need to get the physical address of this register to use it.

I don't think that really explains what's going on here, maybe:

"As part of a workaround for a BootROM issue on Armada 375 Z1, a piece
of assembly code loaded into the Cryptographic Engine SRAM needs to
read the System Controller Resume Address register before the MMU is
enabled. We therefore need a way of getting the physical address for
the System Controller Resume Address register."

> In the previous version of this workaround the physical address were

were -> was.

> hardcoded whereas depending of the Mbus configuration this address may
> change.
> 
> This commit will allow to use the generic boot workaround function
> with the correct address.



> ---
>  arch/arm/mach-mvebu/common.h            |  1 +
>  arch/arm/mach-mvebu/system-controller.c | 11 +++++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
> index b67fb7a10d8b..6ad62cf8352c 100644
> --- a/arch/arm/mach-mvebu/common.h
> +++ b/arch/arm/mach-mvebu/common.h
> @@ -20,6 +20,7 @@
>  void mvebu_restart(enum reboot_mode mode, const char *cmd);
>  int mvebu_cpu_reset_deassert(int cpu);
>  void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
> +u32 mvebu_system_controller_get_phys_addr(void);
>  void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
>  
>  void armada_xp_cpu_die(unsigned int cpu);
> diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
> index 0c5524ac75b7..ae6ab543aa36 100644
> --- a/arch/arm/mach-mvebu/system-controller.c
> +++ b/arch/arm/mach-mvebu/system-controller.c
> @@ -30,6 +30,7 @@
>  #include "common.h"
>  
>  static void __iomem *system_controller_base;
> +static u32 system_controller_phys_base;
>  
>  struct mvebu_system_controller {
>  	u32 rstoutn_mask_offset;
> @@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
>  	writel(virt_to_phys(boot_addr), system_controller_base +
>  	       mvebu_sc->resume_boot_addr);
>  }
> +
> +u32 mvebu_system_controller_get_phys_addr(void)

phys_addr_t should be the return type.

> +{
> +	BUG_ON(system_controller_phys_base == NULL);
> +	BUG_ON(mvebu_sc->resume_boot_addr == 0);
> +	return system_controller_phys_base + mvebu_sc->resume_boot_addr;

So the function name suggests you're returning the base physical address
of the System Controller registers, while you're in fact returning the
physical address of one particular register (the Resume Address one). I
believe the function is misnamed.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
@ 2014-06-30 12:46     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:46 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

I'm not sure that the best approach to solve this problem. Instead,
maybe the system-controller.c code should set up the boot address
workaround on Armada 375. Since the workaround on 375 is really related
to setting the boot address which is done by the system controller,
maybe the initialization of the workaround belongs in
system-controller.c ?

On Fri, 27 Jun 2014 15:22:44 +0200, Gregory CLEMENT wrote:
> In order to boot the secondary CPUs on Armada 375 Z1, we need to read
> the boot address of these CPUs through a register part of the System
> Controller. This done very early where MMU is not enable yet, so we
> need to get the physical address of this register to use it.

I don't think that really explains what's going on here, maybe:

"As part of a workaround for a BootROM issue on Armada 375 Z1, a piece
of assembly code loaded into the Cryptographic Engine SRAM needs to
read the System Controller Resume Address register before the MMU is
enabled. We therefore need a way of getting the physical address for
the System Controller Resume Address register."

> In the previous version of this workaround the physical address were

were -> was.

> hardcoded whereas depending of the Mbus configuration this address may
> change.
> 
> This commit will allow to use the generic boot workaround function
> with the correct address.



> ---
>  arch/arm/mach-mvebu/common.h            |  1 +
>  arch/arm/mach-mvebu/system-controller.c | 11 +++++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
> index b67fb7a10d8b..6ad62cf8352c 100644
> --- a/arch/arm/mach-mvebu/common.h
> +++ b/arch/arm/mach-mvebu/common.h
> @@ -20,6 +20,7 @@
>  void mvebu_restart(enum reboot_mode mode, const char *cmd);
>  int mvebu_cpu_reset_deassert(int cpu);
>  void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
> +u32 mvebu_system_controller_get_phys_addr(void);
>  void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
>  
>  void armada_xp_cpu_die(unsigned int cpu);
> diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
> index 0c5524ac75b7..ae6ab543aa36 100644
> --- a/arch/arm/mach-mvebu/system-controller.c
> +++ b/arch/arm/mach-mvebu/system-controller.c
> @@ -30,6 +30,7 @@
>  #include "common.h"
>  
>  static void __iomem *system_controller_base;
> +static u32 system_controller_phys_base;
>  
>  struct mvebu_system_controller {
>  	u32 rstoutn_mask_offset;
> @@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
>  	writel(virt_to_phys(boot_addr), system_controller_base +
>  	       mvebu_sc->resume_boot_addr);
>  }
> +
> +u32 mvebu_system_controller_get_phys_addr(void)

phys_addr_t should be the return type.

> +{
> +	BUG_ON(system_controller_phys_base == NULL);
> +	BUG_ON(mvebu_sc->resume_boot_addr == 0);
> +	return system_controller_phys_base + mvebu_sc->resume_boot_addr;

So the function name suggests you're returning the base physical address
of the System Controller registers, while you're in fact returning the
physical address of one particular register (the Resume Address one). I
believe the function is misnamed.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 12:50     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:50 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:46 +0200, Gregory CLEMENT wrote:
> On Armada 370, there is "a slow exit process from the deep idle state
> due to heavy L1/L2 cache cleanup operations performed by the BootROM
> software" (cf errata GL-BootROM-10). To avoid this, we replace the
> restart code of the BootROM by a simple jump to the boot address. Then
> the code located at this boot address will take care of the
> initialization.
> 
> For this purpose, we use the common function mvebu_boot_addr_wa()
> introduced in the previous commit.

"in the previous commit" would make sense if the commit immediately
before this one in the series was the one you would be referencing. But
that's not the case here, so it should be either: "introduced in one of
the previous commits", or better "introduced in commit <title of the
commit>".

>  #define PMSU_BASE_OFFSET    0x100
>  #define PMSU_REG_SIZE	    0x1000
> @@ -77,6 +76,9 @@ extern void ll_enable_coherency(void);
>  
>  extern void armada_370_xp_cpu_resume(void);
>  
> +static unsigned long pmsu_mp_phys_base;

phys_addr_t.

> +static void __iomem *pmsu_mp_base;
> +
>  static struct platform_device armada_xp_cpuidle_device = {
>  	.name = "cpuidle-armada-370-xp",
>  };
> @@ -147,6 +149,8 @@ static int __init armada_370_xp_pmsu_init(void)
>  		goto out;
>  	}
>  
> +	pmsu_mp_phys_base = res.start;
> +
>  	pmsu_mp_base = ioremap(res.start, resource_size(&res));
>  	if (!pmsu_mp_base) {
>  		pr_err("unable to map registers\n");
> @@ -312,6 +316,18 @@ int __init armada_370_xp_cpu_pm_init(void)
>  		return 0;
>  	of_node_put(np);
>  
> +	/*
> +	 * On Armada 370, there is "a slow exit process from the deep
> +	 * idle state due to heavy L1/L2 cache cleanup operations
> +	 * performed by the BootROM software". To avoid this, we
> +	 * replace the restart code of the bootrom by a a simple jump
> +	 * to the boot address. Then the code located at this boot
> +	 * address will take care of the initialization.
> +	 */
> +	if (of_machine_is_compatible("marvell,armada370"))
> +		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
> +				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
> +
>  	armada_370_xp_pmsu_enable_l2_powerdown_onidle();
>  	armada_xp_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
>  	platform_device_register(&armada_xp_cpuidle_device);

Other than that, looks good to me.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370
@ 2014-06-30 12:50     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:46 +0200, Gregory CLEMENT wrote:
> On Armada 370, there is "a slow exit process from the deep idle state
> due to heavy L1/L2 cache cleanup operations performed by the BootROM
> software" (cf errata GL-BootROM-10). To avoid this, we replace the
> restart code of the BootROM by a simple jump to the boot address. Then
> the code located at this boot address will take care of the
> initialization.
> 
> For this purpose, we use the common function mvebu_boot_addr_wa()
> introduced in the previous commit.

"in the previous commit" would make sense if the commit immediately
before this one in the series was the one you would be referencing. But
that's not the case here, so it should be either: "introduced in one of
the previous commits", or better "introduced in commit <title of the
commit>".

>  #define PMSU_BASE_OFFSET    0x100
>  #define PMSU_REG_SIZE	    0x1000
> @@ -77,6 +76,9 @@ extern void ll_enable_coherency(void);
>  
>  extern void armada_370_xp_cpu_resume(void);
>  
> +static unsigned long pmsu_mp_phys_base;

phys_addr_t.

> +static void __iomem *pmsu_mp_base;
> +
>  static struct platform_device armada_xp_cpuidle_device = {
>  	.name = "cpuidle-armada-370-xp",
>  };
> @@ -147,6 +149,8 @@ static int __init armada_370_xp_pmsu_init(void)
>  		goto out;
>  	}
>  
> +	pmsu_mp_phys_base = res.start;
> +
>  	pmsu_mp_base = ioremap(res.start, resource_size(&res));
>  	if (!pmsu_mp_base) {
>  		pr_err("unable to map registers\n");
> @@ -312,6 +316,18 @@ int __init armada_370_xp_cpu_pm_init(void)
>  		return 0;
>  	of_node_put(np);
>  
> +	/*
> +	 * On Armada 370, there is "a slow exit process from the deep
> +	 * idle state due to heavy L1/L2 cache cleanup operations
> +	 * performed by the BootROM software". To avoid this, we
> +	 * replace the restart code of the bootrom by a a simple jump
> +	 * to the boot address. Then the code located at this boot
> +	 * address will take care of the initialization.
> +	 */
> +	if (of_machine_is_compatible("marvell,armada370"))
> +		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
> +				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
> +
>  	armada_370_xp_pmsu_enable_l2_powerdown_onidle();
>  	armada_xp_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
>  	platform_device_register(&armada_xp_cpuidle_device);

Other than that, looks good to me.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 06/16] ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 12:57     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:57 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:47 +0200, Gregory CLEMENT wrote:
> Actually most of the function related to the PMSU are not specific to
> the Armada 370 or Armada XP SoCs, but can also be used for most of the
> other mvebu ARMv7 SoCs.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c | 40 ++++++++++++++++++++--------------------
>  1 file changed, 20 insertions(+), 20 deletions(-)

I'm fine on the principle, but this badly conflicts with the PMSU
changes I've made to support CPU hotplug, which are already in
linux-next. See
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/log/arch/arm/mach-mvebu/pmsu.c.

>  /* No locking is needed because we only access per-CPU registers */
> -void armada_370_xp_pmsu_idle_prepare(bool deepidle)
> +static void mvebu_v7_pmsu_idle_prepare(bool deepidle)

Also, note here that you're not only renaming, but also adding the
'static' qualifier. This is already done in linux-next by
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/arch/arm/mach-mvebu/pmsu.c?id=adb1d99384c7480886153a97d2ea22e9c0d2e053,
but the function is anyway renamed in
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/arch/arm/mach-mvebu/pmsu.c?id=bbb92284b6c821e9434223d437fbd10b8a24c294
as a preparation for CPU hotplug support.

> -static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
> +static noinline int do_armada_xp_370_cpu_suspend(unsigned long deepidle)

This does not seem like a rename to mvebu_v7.

>  {
> -	armada_370_xp_pmsu_idle_prepare(deepidle);
> +	mvebu_v7_pmsu_idle_prepare(deepidle);
>  
>  	v7_exit_coherency_flush(all);
>  
> @@ -248,13 +248,13 @@ static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
>  	return 0;
>  }
>  
> -static int armada_370_xp_cpu_suspend(unsigned long deepidle)
> +static int armada_xp_370_cpu_suspend(unsigned long deepidle)

Ditto.

>  {
> -	return cpu_suspend(deepidle, do_armada_370_xp_cpu_suspend);
> +	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);

Ditto.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 06/16] ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
@ 2014-06-30 12:57     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 12:57 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:47 +0200, Gregory CLEMENT wrote:
> Actually most of the function related to the PMSU are not specific to
> the Armada 370 or Armada XP SoCs, but can also be used for most of the
> other mvebu ARMv7 SoCs.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
>  arch/arm/mach-mvebu/pmsu.c | 40 ++++++++++++++++++++--------------------
>  1 file changed, 20 insertions(+), 20 deletions(-)

I'm fine on the principle, but this badly conflicts with the PMSU
changes I've made to support CPU hotplug, which are already in
linux-next. See
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/log/arch/arm/mach-mvebu/pmsu.c.

>  /* No locking is needed because we only access per-CPU registers */
> -void armada_370_xp_pmsu_idle_prepare(bool deepidle)
> +static void mvebu_v7_pmsu_idle_prepare(bool deepidle)

Also, note here that you're not only renaming, but also adding the
'static' qualifier. This is already done in linux-next by
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/arch/arm/mach-mvebu/pmsu.c?id=adb1d99384c7480886153a97d2ea22e9c0d2e053,
but the function is anyway renamed in
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/arch/arm/mach-mvebu/pmsu.c?id=bbb92284b6c821e9434223d437fbd10b8a24c294
as a preparation for CPU hotplug support.

> -static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
> +static noinline int do_armada_xp_370_cpu_suspend(unsigned long deepidle)

This does not seem like a rename to mvebu_v7.

>  {
> -	armada_370_xp_pmsu_idle_prepare(deepidle);
> +	mvebu_v7_pmsu_idle_prepare(deepidle);
>  
>  	v7_exit_coherency_flush(all);
>  
> @@ -248,13 +248,13 @@ static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
>  	return 0;
>  }
>  
> -static int armada_370_xp_cpu_suspend(unsigned long deepidle)
> +static int armada_xp_370_cpu_suspend(unsigned long deepidle)

Ditto.

>  {
> -	return cpu_suspend(deepidle, do_armada_370_xp_cpu_suspend);
> +	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);

Ditto.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 12/16] cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 13:28     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 13:28 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:53 +0200, Gregory CLEMENT wrote:
> Actually this driver will be able to manage the cpuidle for more SoCs
> that Armada 370 ad XP. It will support Armada 38x and potentially
> Armada 375. This patch change the names accordingly to this behavior.

I think the last sentence should rather be something like: "This patch
renames the driver as well as the functions and variables used in the
driver".

I would also specifically mention the renaming of the driver that
requires changing the pmsu.c file. It is worth mentioning that this
rename, touching both drivers/cpuidle and arch/arm/mach-mvebu, may
require some special handling in terms of patch merging (the patch
mainly touches drivers/cpuidle so it should theoretically go through
the cpuidle maintainer, but since the pmsu.c file is touched a lot by
other patches, there will probably be lots of conflicts if this patch
goes through the cpuidle tree). Surely something to mention as a
comment in the patch, maybe to get the Acked-by of the cpuidle people
and merge things through the mvebu and arm-soc trees.

> -config ARM_ARMADA_370_XP_CPUIDLE
> -	bool "CPU Idle Driver for Armada 370/XP family processors"
> +config ARM_MVEBU_V7_CPUIDLE
> +	bool "CPU Idle Driver for mvebu v7 family processors"

Actually, what worries me a bit of that Dove is a ARMv7 processor of
the mvebu family, but which is not using this cpuidle driver. Do you
expect Dove to be able to use this driver in the future?

>  	depends on ARCH_MVEBU
>  	help
> -	  Select this to enable cpuidle on Armada 370/XP processors.
> +	  Select this to enable cpuidle on Armada 370, 385 and XP processors.

385 -> 38x, because 380 and 385 are both capable of using this driver.

> diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c
> deleted file mode 100644
> index a5fba0287bfb..000000000000
> --- a/drivers/cpuidle/cpuidle-armada-370-xp.c
> +++ /dev/null

You haven't enabled rename detection in git? Or git isn't detecting the
rename because of the number of changes in the file?

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 12/16] cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
@ 2014-06-30 13:28     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 13:28 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:53 +0200, Gregory CLEMENT wrote:
> Actually this driver will be able to manage the cpuidle for more SoCs
> that Armada 370 ad XP. It will support Armada 38x and potentially
> Armada 375. This patch change the names accordingly to this behavior.

I think the last sentence should rather be something like: "This patch
renames the driver as well as the functions and variables used in the
driver".

I would also specifically mention the renaming of the driver that
requires changing the pmsu.c file. It is worth mentioning that this
rename, touching both drivers/cpuidle and arch/arm/mach-mvebu, may
require some special handling in terms of patch merging (the patch
mainly touches drivers/cpuidle so it should theoretically go through
the cpuidle maintainer, but since the pmsu.c file is touched a lot by
other patches, there will probably be lots of conflicts if this patch
goes through the cpuidle tree). Surely something to mention as a
comment in the patch, maybe to get the Acked-by of the cpuidle people
and merge things through the mvebu and arm-soc trees.

> -config ARM_ARMADA_370_XP_CPUIDLE
> -	bool "CPU Idle Driver for Armada 370/XP family processors"
> +config ARM_MVEBU_V7_CPUIDLE
> +	bool "CPU Idle Driver for mvebu v7 family processors"

Actually, what worries me a bit of that Dove is a ARMv7 processor of
the mvebu family, but which is not using this cpuidle driver. Do you
expect Dove to be able to use this driver in the future?

>  	depends on ARCH_MVEBU
>  	help
> -	  Select this to enable cpuidle on Armada 370/XP processors.
> +	  Select this to enable cpuidle on Armada 370, 385 and XP processors.

385 -> 38x, because 380 and 385 are both capable of using this driver.

> diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c
> deleted file mode 100644
> index a5fba0287bfb..000000000000
> --- a/drivers/cpuidle/cpuidle-armada-370-xp.c
> +++ /dev/null

You haven't enabled rename detection in git? Or git isn't detecting the
rename because of the number of changes in the file?

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 13/16] cpuidle: mvebu: Move the description of the cpuidle states in the platform part
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 13:32     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 13:32 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:54 +0200, Gregory CLEMENT wrote:
> In order to prepare the add of new SoCs supports for this cpuidle

"the add of new SoCs supports for this cpuidle" -> "the addition of the
support for more SoCs in this cpuidle".

> driver, this patch moves the description of the state in the platform
> part. Indeed the number of the cpuidle state, and the value of the
> flag used will vary depending of the SoC.

I actually don't really agree with the reasoning here. We can perfectly
fine have several separate compatible strings, one for each SoC. We do
this for pinctrl, for clocks, and for many other drivers. Why should it
be different for the cpuidle driver? I know the function to enter idle
will most likely implemented in arch/arm/mach-mvebu/ because those
functions are generally too tightly coupled with a bunch of system
registers changes, but the description of the different idle states can
just as well be inside the cpuidle driver itself.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 13/16] cpuidle: mvebu: Move the description of the cpuidle states in the platform part
@ 2014-06-30 13:32     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:54 +0200, Gregory CLEMENT wrote:
> In order to prepare the add of new SoCs supports for this cpuidle

"the add of new SoCs supports for this cpuidle" -> "the addition of the
support for more SoCs in this cpuidle".

> driver, this patch moves the description of the state in the platform
> part. Indeed the number of the cpuidle state, and the value of the
> flag used will vary depending of the SoC.

I actually don't really agree with the reasoning here. We can perfectly
fine have several separate compatible strings, one for each SoC. We do
this for pinctrl, for clocks, and for many other drivers. Why should it
be different for the cpuidle driver? I know the function to enter idle
will most likely implemented in arch/arm/mach-mvebu/ because those
functions are generally too tightly coupled with a bunch of system
registers changes, but the description of the different idle states can
just as well be inside the cpuidle driver itself.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 14/16] ARM: mvebu: Add CPU idle support for Armada 370
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 13:36     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 13:36 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:55 +0200, Gregory CLEMENT wrote:
> Unlike the Armada XP the Armada 370 always power done the L2 cache, so

power -> powers
done -> down

> it have only 2 cpuidle states. Thanks to the previous patches, adding

have -> has.

> the support for this new SoCs required only the modification of the

required -> requires.

> architecture specific part.

May not be true if we move the cpuidle states back into the cpuidle
driver, as I suggested in a comment to one of the previous patch.

> The message in case of failure to suspend the system was switched from
> warn to debug. Indeed due to the "slow exit process from the deep idle
> state" in Armada 370, this situation happens quite often. Using the
> _debug version avoids spamming the kernel logs, but still allows to
> enable it if needed.

Is it really expected that the system fails to enter the idle state? I
must say I don't really see the relation with the slow exit from deep
idle state, because the do_armada_xp_370_cpu_suspend() function is only
here to *enter* the idle state, so how is entering the deep idle state
related to an issue when exiting the idle state?


> +static struct mvebu_v7_cpuidle armada_370_cpuidle = {
> +	.mvebu_v7_idle_driver = {
> +		.name			= "armada_370_idle",
> +		.states[0]		= ARM_CPUIDLE_WFI_STATE,
> +		.states[1]		= {
> +			.exit_latency		= 100,
> +			.power_usage		= 5,
> +			.target_residency	= 1000,
> +			.flags			= CPUIDLE_FLAG_TIME_VALID |
> +			MVEBU_V7_FLAG_DEEP_IDLE,
> +			.name			= "Deep Idle",
> +			.desc			= "CPU and L2 Fabric power down",
> +		},
> +		.state_count = 2,
> +	},
> +	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
> +};

As I said, I'd prefer to see this in the cpuidle driver.

> +
>  static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
>  	.mvebu_v7_idle_driver = {
>  		.name			= "armada_xp_idle",
> @@ -328,6 +346,31 @@ static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
>  	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
>  };
>  
> +static __init bool armada_370_cpuidle_init(void)
> +{
> +	struct device_node *np;
> +
> +	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> +	if (!np)
> +		return false;
> +	of_node_put(np);
> +
> +	/*
> +	 * On Armada 370, there is "a slow exit process from the deep
> +	 * idle state due to heavy L1/L2 cache cleanup operations
> +	 * performed by the BootROM software". To avoid this, we
> +	 * replace the restart code of the bootrom by a a simple jump
> +	 * to the boot address. Then the code located at this boot
> +	 * address will take care of the initialization.
> +	 */
> +	mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
> +			PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
> +
> +	mvebu_cpu_resume = armada_370_xp_cpu_resume;
> +	mvebu_v7_cpuidle_device.dev.platform_data = &armada_370_cpuidle;
> +	return true;
> +}
> +
>  static __init bool armada_xp_cpuidle_init(void)
>  {
>  	struct device_node *np;
> @@ -345,6 +388,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
>  	{ .compatible = "marvell,armadaxp",
>  	  .data = (void *)armada_xp_cpuidle_init,
>  	},
> +	{ .compatible = "marvell,armada370",
> +	  .data = (void *)armada_370_cpuidle_init,
> +	},
>  	{ /* end of list */ },
>  };
>  
> @@ -373,18 +419,6 @@ static int __init mvebu_v7_cpu_pm_init(void)
>  		return 0;
>  	of_node_put(np);
>  
> -	/*
> -	 * On Armada 370, there is "a slow exit process from the deep
> -	 * idle state due to heavy L1/L2 cache cleanup operations
> -	 * performed by the BootROM software". To avoid this, we
> -	 * replace the restart code of the bootrom by a a simple jump
> -	 * to the boot address. Then the code located at this boot
> -	 * address will take care of the initialization.
> -	 */
> -	if (of_machine_is_compatible("marvell,armada370"))
> -		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
> -				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));

So we're almost entirely reverting/moving the code added by "[PATCH
05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370".
Maybe there is an issue in your series, and the workaround for cpuidle
support on Armada 370 should only be added in this patch, and not
earlier?

> -
>  	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
>  	platform_device_register(&mvebu_v7_cpuidle_device);
>  	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 14/16] ARM: mvebu: Add CPU idle support for Armada 370
@ 2014-06-30 13:36     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 13:36 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:55 +0200, Gregory CLEMENT wrote:
> Unlike the Armada XP the Armada 370 always power done the L2 cache, so

power -> powers
done -> down

> it have only 2 cpuidle states. Thanks to the previous patches, adding

have -> has.

> the support for this new SoCs required only the modification of the

required -> requires.

> architecture specific part.

May not be true if we move the cpuidle states back into the cpuidle
driver, as I suggested in a comment to one of the previous patch.

> The message in case of failure to suspend the system was switched from
> warn to debug. Indeed due to the "slow exit process from the deep idle
> state" in Armada 370, this situation happens quite often. Using the
> _debug version avoids spamming the kernel logs, but still allows to
> enable it if needed.

Is it really expected that the system fails to enter the idle state? I
must say I don't really see the relation with the slow exit from deep
idle state, because the do_armada_xp_370_cpu_suspend() function is only
here to *enter* the idle state, so how is entering the deep idle state
related to an issue when exiting the idle state?


> +static struct mvebu_v7_cpuidle armada_370_cpuidle = {
> +	.mvebu_v7_idle_driver = {
> +		.name			= "armada_370_idle",
> +		.states[0]		= ARM_CPUIDLE_WFI_STATE,
> +		.states[1]		= {
> +			.exit_latency		= 100,
> +			.power_usage		= 5,
> +			.target_residency	= 1000,
> +			.flags			= CPUIDLE_FLAG_TIME_VALID |
> +			MVEBU_V7_FLAG_DEEP_IDLE,
> +			.name			= "Deep Idle",
> +			.desc			= "CPU and L2 Fabric power down",
> +		},
> +		.state_count = 2,
> +	},
> +	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
> +};

As I said, I'd prefer to see this in the cpuidle driver.

> +
>  static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
>  	.mvebu_v7_idle_driver = {
>  		.name			= "armada_xp_idle",
> @@ -328,6 +346,31 @@ static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
>  	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
>  };
>  
> +static __init bool armada_370_cpuidle_init(void)
> +{
> +	struct device_node *np;
> +
> +	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> +	if (!np)
> +		return false;
> +	of_node_put(np);
> +
> +	/*
> +	 * On Armada 370, there is "a slow exit process from the deep
> +	 * idle state due to heavy L1/L2 cache cleanup operations
> +	 * performed by the BootROM software". To avoid this, we
> +	 * replace the restart code of the bootrom by a a simple jump
> +	 * to the boot address. Then the code located at this boot
> +	 * address will take care of the initialization.
> +	 */
> +	mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
> +			PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
> +
> +	mvebu_cpu_resume = armada_370_xp_cpu_resume;
> +	mvebu_v7_cpuidle_device.dev.platform_data = &armada_370_cpuidle;
> +	return true;
> +}
> +
>  static __init bool armada_xp_cpuidle_init(void)
>  {
>  	struct device_node *np;
> @@ -345,6 +388,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
>  	{ .compatible = "marvell,armadaxp",
>  	  .data = (void *)armada_xp_cpuidle_init,
>  	},
> +	{ .compatible = "marvell,armada370",
> +	  .data = (void *)armada_370_cpuidle_init,
> +	},
>  	{ /* end of list */ },
>  };
>  
> @@ -373,18 +419,6 @@ static int __init mvebu_v7_cpu_pm_init(void)
>  		return 0;
>  	of_node_put(np);
>  
> -	/*
> -	 * On Armada 370, there is "a slow exit process from the deep
> -	 * idle state due to heavy L1/L2 cache cleanup operations
> -	 * performed by the BootROM software". To avoid this, we
> -	 * replace the restart code of the bootrom by a a simple jump
> -	 * to the boot address. Then the code located at this boot
> -	 * address will take care of the initialization.
> -	 */
> -	if (of_machine_is_compatible("marvell,armada370"))
> -		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
> -				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));

So we're almost entirely reverting/moving the code added by "[PATCH
05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370".
Maybe there is an issue in your series, and the workaround for cpuidle
support on Armada 370 should only be added in this patch, and not
earlier?

> -
>  	mvebu_v7_pmsu_enable_l2_powerdown_onidle();
>  	platform_device_register(&mvebu_v7_cpuidle_device);
>  	cpu_pm_register_notifier(&mvebu_v7_cpu_pm_notifier);

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 14:07     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 14:07 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:48 +0200, Gregory CLEMENT wrote:

> +static bool (*mvebu_v7_cpu_idle_init)(void);
> +
> +static __init bool armada_xp_cpuidle_init(void)
> +{
> +	struct device_node *np;
> +
> +	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> +	if (!np)
> +		return false;
> +	of_node_put(np);
> +
> +	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
> +	return true;
> +}
> +
> +static struct of_device_id of_cpuidle_table[] __initdata = {
> +	{ .compatible = "marvell,armadaxp",
> +	  .data = (void *)armada_xp_cpuidle_init,
> +	},
> +	{ /* end of list */ },
> +};
> +
>  static int __init mvebu_v7_cpu_pm_init(void)
>  {
>  	struct device_node *np;
> +	const struct of_device_id *match;
> +
> +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
> +					&match);

I'm not sure I like using of_find_matching_node_and_match() on the
entire tree to find the root node compatible string. Wouldn't it be
simpler and shorter to just do:

	if (of_machine_is_compatible("marvell,armadaxp"))
		ret = armadaxp_cpuidle_init();
	else if (of_machine_is_compatible("marvell,armada370"))
		ret = armada370_cpuidle_init();
	else if (of_machine_is_compaitble("marvell,armada380"))
		ret = armada38x_cpuidle_init();

	if (ret)
		return ret;

Also, using a boolean to return a success/error status is not the
kernel way of doing things, you should use an int instead and use
proper error codes or return 0 on success.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
@ 2014-06-30 14:07     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 14:07 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:48 +0200, Gregory CLEMENT wrote:

> +static bool (*mvebu_v7_cpu_idle_init)(void);
> +
> +static __init bool armada_xp_cpuidle_init(void)
> +{
> +	struct device_node *np;
> +
> +	np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
> +	if (!np)
> +		return false;
> +	of_node_put(np);
> +
> +	mvebu_v7_cpuidle_device.dev.platform_data = armada_xp_370_cpu_suspend;
> +	return true;
> +}
> +
> +static struct of_device_id of_cpuidle_table[] __initdata = {
> +	{ .compatible = "marvell,armadaxp",
> +	  .data = (void *)armada_xp_cpuidle_init,
> +	},
> +	{ /* end of list */ },
> +};
> +
>  static int __init mvebu_v7_cpu_pm_init(void)
>  {
>  	struct device_node *np;
> +	const struct of_device_id *match;
> +
> +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
> +					&match);

I'm not sure I like using of_find_matching_node_and_match() on the
entire tree to find the root node compatible string. Wouldn't it be
simpler and shorter to just do:

	if (of_machine_is_compatible("marvell,armadaxp"))
		ret = armadaxp_cpuidle_init();
	else if (of_machine_is_compatible("marvell,armada370"))
		ret = armada370_cpuidle_init();
	else if (of_machine_is_compaitble("marvell,armada380"))
		ret = armada38x_cpuidle_init();

	if (ret)
		return ret;

Also, using a boolean to return a success/error status is not the
kernel way of doing things, you should use an int instead and use
proper error codes or return 0 on success.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 15:07     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:07 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:56 +0200, Gregory CLEMENT wrote:

> Unlike the Armada XP and the Armada 370, this SoC uses a Cortex A9
> core.

Isn't there some more details missing in this sentence? When I read it,
at the end of the sentence, I'm wondering "and so what? what does this
implies in terms of cpuidle support?".

> Beside this, the main difference for the cpu idle is the way to
> handle the L2 cache and the use of SCU.

Beside -> Besides.

of SCU -> of the SCU

> +static void __iomem *scu_base;

It's really a shame that the SCU driver isn't a driver on its own,
capable of storing the base address of the SCU instead of having to
pass it around everywhere. But for sure it's not the point of this
patch series to improve this as well.

>  static struct platform_device mvebu_v7_cpuidle_device = {
> @@ -151,6 +168,7 @@ static int __init mvebu_v7_pmsu_init(void)
>  				np->full_name)) {
>  		pr_err("unable to request region\n");
>  		ret = -EBUSY;
> +

This change.

>  		goto out;
>  	}
>  
> @@ -163,7 +181,6 @@ static int __init mvebu_v7_pmsu_init(void)
>  		ret = -ENOMEM;
>  		goto out;
>  	}
> -

And this one look like spurious changes not related to the patch.

>   out:
>  	of_node_put(np);
>  	return ret;
> @@ -260,6 +277,27 @@ static int armada_xp_370_cpu_suspend(unsigned long deepidle)
>  	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
>  }
>  
> +static noinline int do_armada_38x_cpu_suspend(unsigned long deepidle)
> +{
> +	mvebu_v7_pmsu_idle_prepare(deepidle, false);
> +	/*
> +	 * Already flushed cache, but do it again as the outer cache
> +	 * functions dirty the cache with spinlocks
> +	 */
> +	v7_exit_coherency_flush(louis);
> +
> +	scu_power_mode(scu_base, SCU_PM_POWEROFF);
> +
> +	cpu_do_idle();

I see cpu_do_idle() does dsb() and wfi(), so why don't we use in the
do_armada_370_xp_cpu_suspend() function ?

> +
> +	return 1;

You return 1 here, but in the do_armada_370_xp_cpu_suspend() function
you return zero. Is the return value being used? Why use 0 in one case
and 1 in the other?

> +}
> +
> +static int armada_38x_cpu_suspend(unsigned long deepidle)
> +{
> +	return cpu_suspend(false, do_armada_38x_cpu_suspend);
> +}
> +
>  /* No locking is needed because we only access per-CPU registers */
>  static noinline void mvebu_v7_pmsu_idle_restore(void)
>  {
> @@ -268,7 +306,6 @@ static noinline void mvebu_v7_pmsu_idle_restore(void)
>  
>  	if (pmsu_mp_base == NULL)
>  		return;
> -

Spurious change.

>  	/* cancel ask HW to power down the L2 Cache if possible */
>  	reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
>  	reg &= ~PMSU_CONTROL_AND_CONFIG_L2_PWDDN;
> @@ -320,6 +357,23 @@ static struct mvebu_v7_cpuidle armada_370_cpuidle = {
>  	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
>  };
>  
> +static struct mvebu_v7_cpuidle armada_38x_cpuidle = {
> +	.mvebu_v7_idle_driver = {
> +		.name			= "armada_38x_idle",
> +		.states[0]		= ARM_CPUIDLE_WFI_STATE,
> +		.states[1]		= {
> +			.exit_latency		= 10,
> +			.power_usage		= 5,
> +			.target_residency	= 100,
> +			.flags			= CPUIDLE_FLAG_TIME_VALID,
> +			.name			= "Idle",
> +			.desc			= "CPU and SCU power down",
> +		},
> +		.state_count = 2,
> +	},
> +	.mvebu_v7_cpu_suspend = armada_38x_cpu_suspend,
> +};

Should go to the cpuidle driver, IMO.

>  static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
>  	.mvebu_v7_idle_driver = {
>  		.name			= "armada_xp_idle",
> @@ -371,6 +425,46 @@ static __init bool armada_370_cpuidle_init(void)
>  	return true;
>  }
>  
> +static __init bool armada_38x_cpuidle_init(void)

As mentioned earlier, this function should return an 'int'.

> +{
> +	struct device_node *np;
> +	void __iomem *mpsoc_base;
> +	u32 reg;
> +
> +	np = of_find_compatible_node(NULL, NULL,
> +				"marvell,armada-380-coherency-fabric");
> +	if (!np)
> +		return false;

		return -ENODEV;

> +	of_node_put(np);
> +
> +	np = of_find_compatible_node(NULL, NULL,
> +				"marvell,armada-380-mpcore-soc-ctrl");
> +	if (!np)
> +		return false;

		return -ENODEV;

> +	mpsoc_base = of_iomap(np, 0);
> +	WARN_ON(!mpsoc_base);

WARN_ON() seems a bit weak for something that will make the next line
crash the kernel. What about:

	if (!mpsoc_base)
		return -ENOMEM;

I think the of_node_put(np) should be here.

> +
> +	/* Set up reset mask when powering down the cpus */
> +	reg = readl(mpsoc_base + MPCORE_RESET_CTL);
> +	reg |= MPCORE_RESET_CTL_L2;
> +	reg |= MPCORE_RESET_CTL_DEBUG;
> +	writel(reg, mpsoc_base + MPCORE_RESET_CTL);
> +	iounmap(mpsoc_base);
> +	of_node_put(np);
> +
> +	/* Set up delay */
> +	reg = readl(pmsu_mp_base + PMSU_POWERDOWN_DELAY);
> +	reg &= ~PMSU_POWERDOWN_DELAY_MASK;
> +	reg |= PMSU_DFLT_ARMADA38X_DELAY;
> +	reg |= PMSU_POWERDOWN_DELAY_PMU;
> +	writel(reg, pmsu_mp_base + PMSU_POWERDOWN_DELAY);
> +
> +	scu_base = mvebu_get_scu_base();
> +	mvebu_cpu_resume = armada_38x_cpu_resume;
> +	mvebu_v7_cpuidle_device.dev.platform_data = &armada_38x_cpuidle;
> +	return true;

	return 0;

> +}
> +
>  static __init bool armada_xp_cpuidle_init(void)
>  {
>  	struct device_node *np;
> @@ -391,6 +485,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
>  	{ .compatible = "marvell,armada370",
>  	  .data = (void *)armada_370_cpuidle_init,
>  	},
> +	{ .compatible = "marvell,armada380",
> +	  .data = (void *)armada_38x_cpuidle_init,
> +	},

As mentioned in the comments to a previous commit, I'm not sure using a
match table is the best idea here.

>  	{ /* end of list */ },
>  };
>  
> diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
> index 3b702a16bd3d..15b823dff61a 100644
> --- a/arch/arm/mach-mvebu/pmsu_ll.S
> +++ b/arch/arm/mach-mvebu/pmsu_ll.S
> @@ -23,6 +23,20 @@ ARM_BE8(setend	be )			@ go BE8 if entered LE
>  	b	cpu_resume
>  ENDPROC(armada_370_xp_cpu_resume)
>  
> +ENTRY(armada_38x_cpu_resume)
> +	/* do we need it for Armada 38x*/
> +ARM_BE8(setend	be )			@ go BE8 if entered LE

Yes, I believe we will need it. I'll try to do some testing and report.

> +	bl	v7_invalidate_l1
> +	mrc     p15, 4, r1, c15, c0	@ get SCU base address
> +	orr	r1, r1, #0x8		@ SCU CPU Power Status Register
> +	mrc	15, 0, r0, cr0, cr0, 5	@ get the CPU ID
> +	and	r0, r0, #15
> +	add	r1, r1, r0
> +	mov	r0, #0x0
> +	strb	r0, [r1]		@ switch SCU power state to Normal mode
> +	b	cpu_resume
> +ENDPROC(armada_38x_cpu_resume)
> +
>  .global mvebu_boot_wa_start
>  .global mvebu_boot_wa_end
>  

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
@ 2014-06-30 15:07     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:07 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:56 +0200, Gregory CLEMENT wrote:

> Unlike the Armada XP and the Armada 370, this SoC uses a Cortex A9
> core.

Isn't there some more details missing in this sentence? When I read it,
at the end of the sentence, I'm wondering "and so what? what does this
implies in terms of cpuidle support?".

> Beside this, the main difference for the cpu idle is the way to
> handle the L2 cache and the use of SCU.

Beside -> Besides.

of SCU -> of the SCU

> +static void __iomem *scu_base;

It's really a shame that the SCU driver isn't a driver on its own,
capable of storing the base address of the SCU instead of having to
pass it around everywhere. But for sure it's not the point of this
patch series to improve this as well.

>  static struct platform_device mvebu_v7_cpuidle_device = {
> @@ -151,6 +168,7 @@ static int __init mvebu_v7_pmsu_init(void)
>  				np->full_name)) {
>  		pr_err("unable to request region\n");
>  		ret = -EBUSY;
> +

This change.

>  		goto out;
>  	}
>  
> @@ -163,7 +181,6 @@ static int __init mvebu_v7_pmsu_init(void)
>  		ret = -ENOMEM;
>  		goto out;
>  	}
> -

And this one look like spurious changes not related to the patch.

>   out:
>  	of_node_put(np);
>  	return ret;
> @@ -260,6 +277,27 @@ static int armada_xp_370_cpu_suspend(unsigned long deepidle)
>  	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
>  }
>  
> +static noinline int do_armada_38x_cpu_suspend(unsigned long deepidle)
> +{
> +	mvebu_v7_pmsu_idle_prepare(deepidle, false);
> +	/*
> +	 * Already flushed cache, but do it again as the outer cache
> +	 * functions dirty the cache with spinlocks
> +	 */
> +	v7_exit_coherency_flush(louis);
> +
> +	scu_power_mode(scu_base, SCU_PM_POWEROFF);
> +
> +	cpu_do_idle();

I see cpu_do_idle() does dsb() and wfi(), so why don't we use in the
do_armada_370_xp_cpu_suspend() function ?

> +
> +	return 1;

You return 1 here, but in the do_armada_370_xp_cpu_suspend() function
you return zero. Is the return value being used? Why use 0 in one case
and 1 in the other?

> +}
> +
> +static int armada_38x_cpu_suspend(unsigned long deepidle)
> +{
> +	return cpu_suspend(false, do_armada_38x_cpu_suspend);
> +}
> +
>  /* No locking is needed because we only access per-CPU registers */
>  static noinline void mvebu_v7_pmsu_idle_restore(void)
>  {
> @@ -268,7 +306,6 @@ static noinline void mvebu_v7_pmsu_idle_restore(void)
>  
>  	if (pmsu_mp_base == NULL)
>  		return;
> -

Spurious change.

>  	/* cancel ask HW to power down the L2 Cache if possible */
>  	reg = readl(pmsu_mp_base + PMSU_CONTROL_AND_CONFIG(hw_cpu));
>  	reg &= ~PMSU_CONTROL_AND_CONFIG_L2_PWDDN;
> @@ -320,6 +357,23 @@ static struct mvebu_v7_cpuidle armada_370_cpuidle = {
>  	.mvebu_v7_cpu_suspend = armada_xp_370_cpu_suspend,
>  };
>  
> +static struct mvebu_v7_cpuidle armada_38x_cpuidle = {
> +	.mvebu_v7_idle_driver = {
> +		.name			= "armada_38x_idle",
> +		.states[0]		= ARM_CPUIDLE_WFI_STATE,
> +		.states[1]		= {
> +			.exit_latency		= 10,
> +			.power_usage		= 5,
> +			.target_residency	= 100,
> +			.flags			= CPUIDLE_FLAG_TIME_VALID,
> +			.name			= "Idle",
> +			.desc			= "CPU and SCU power down",
> +		},
> +		.state_count = 2,
> +	},
> +	.mvebu_v7_cpu_suspend = armada_38x_cpu_suspend,
> +};

Should go to the cpuidle driver, IMO.

>  static struct mvebu_v7_cpuidle armada_xp_cpuidle = {
>  	.mvebu_v7_idle_driver = {
>  		.name			= "armada_xp_idle",
> @@ -371,6 +425,46 @@ static __init bool armada_370_cpuidle_init(void)
>  	return true;
>  }
>  
> +static __init bool armada_38x_cpuidle_init(void)

As mentioned earlier, this function should return an 'int'.

> +{
> +	struct device_node *np;
> +	void __iomem *mpsoc_base;
> +	u32 reg;
> +
> +	np = of_find_compatible_node(NULL, NULL,
> +				"marvell,armada-380-coherency-fabric");
> +	if (!np)
> +		return false;

		return -ENODEV;

> +	of_node_put(np);
> +
> +	np = of_find_compatible_node(NULL, NULL,
> +				"marvell,armada-380-mpcore-soc-ctrl");
> +	if (!np)
> +		return false;

		return -ENODEV;

> +	mpsoc_base = of_iomap(np, 0);
> +	WARN_ON(!mpsoc_base);

WARN_ON() seems a bit weak for something that will make the next line
crash the kernel. What about:

	if (!mpsoc_base)
		return -ENOMEM;

I think the of_node_put(np) should be here.

> +
> +	/* Set up reset mask when powering down the cpus */
> +	reg = readl(mpsoc_base + MPCORE_RESET_CTL);
> +	reg |= MPCORE_RESET_CTL_L2;
> +	reg |= MPCORE_RESET_CTL_DEBUG;
> +	writel(reg, mpsoc_base + MPCORE_RESET_CTL);
> +	iounmap(mpsoc_base);
> +	of_node_put(np);
> +
> +	/* Set up delay */
> +	reg = readl(pmsu_mp_base + PMSU_POWERDOWN_DELAY);
> +	reg &= ~PMSU_POWERDOWN_DELAY_MASK;
> +	reg |= PMSU_DFLT_ARMADA38X_DELAY;
> +	reg |= PMSU_POWERDOWN_DELAY_PMU;
> +	writel(reg, pmsu_mp_base + PMSU_POWERDOWN_DELAY);
> +
> +	scu_base = mvebu_get_scu_base();
> +	mvebu_cpu_resume = armada_38x_cpu_resume;
> +	mvebu_v7_cpuidle_device.dev.platform_data = &armada_38x_cpuidle;
> +	return true;

	return 0;

> +}
> +
>  static __init bool armada_xp_cpuidle_init(void)
>  {
>  	struct device_node *np;
> @@ -391,6 +485,9 @@ static struct of_device_id of_cpuidle_table[] __initdata = {
>  	{ .compatible = "marvell,armada370",
>  	  .data = (void *)armada_370_cpuidle_init,
>  	},
> +	{ .compatible = "marvell,armada380",
> +	  .data = (void *)armada_38x_cpuidle_init,
> +	},

As mentioned in the comments to a previous commit, I'm not sure using a
match table is the best idea here.

>  	{ /* end of list */ },
>  };
>  
> diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
> index 3b702a16bd3d..15b823dff61a 100644
> --- a/arch/arm/mach-mvebu/pmsu_ll.S
> +++ b/arch/arm/mach-mvebu/pmsu_ll.S
> @@ -23,6 +23,20 @@ ARM_BE8(setend	be )			@ go BE8 if entered LE
>  	b	cpu_resume
>  ENDPROC(armada_370_xp_cpu_resume)
>  
> +ENTRY(armada_38x_cpu_resume)
> +	/* do we need it for Armada 38x*/
> +ARM_BE8(setend	be )			@ go BE8 if entered LE

Yes, I believe we will need it. I'll try to do some testing and report.

> +	bl	v7_invalidate_l1
> +	mrc     p15, 4, r1, c15, c0	@ get SCU base address
> +	orr	r1, r1, #0x8		@ SCU CPU Power Status Register
> +	mrc	15, 0, r0, cr0, cr0, 5	@ get the CPU ID
> +	and	r0, r0, #15
> +	add	r1, r1, r0
> +	mov	r0, #0x0
> +	strb	r0, [r1]		@ switch SCU power state to Normal mode
> +	b	cpu_resume
> +ENDPROC(armada_38x_cpu_resume)
> +
>  .global mvebu_boot_wa_start
>  .global mvebu_boot_wa_end
>  

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 08/16] ARM: mvebu: Use a local variable to store the resume address
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 15:09     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:09 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:49 +0200, Gregory CLEMENT wrote:

> +static void *mvebu_cpu_resume;
> +
>  static struct platform_device mvebu_v7_cpuidle_device = {
>  	.name = "cpuidle-armada-370-xp",
>  };
> @@ -281,7 +283,7 @@ static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
>  {
>  	if (action == CPU_PM_ENTER) {
>  		unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
> -		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
> +		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cpu_resume);

Instead of doing this in the CPU_PM_ENTER notifier, do we have a reason
to not do it in the do_armada_370_xp_cpu_suspend() function, and then
do_armada_38x_suspend() function respectively? Those functions are
already SoC-specific, so surely, they already know whether the resume
path should go through armada_370_xp_cpu_resume() or
armada_38x_cpu_resume(), no?

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 08/16] ARM: mvebu: Use a local variable to store the resume address
@ 2014-06-30 15:09     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:49 +0200, Gregory CLEMENT wrote:

> +static void *mvebu_cpu_resume;
> +
>  static struct platform_device mvebu_v7_cpuidle_device = {
>  	.name = "cpuidle-armada-370-xp",
>  };
> @@ -281,7 +283,7 @@ static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
>  {
>  	if (action == CPU_PM_ENTER) {
>  		unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
> -		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
> +		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cpu_resume);

Instead of doing this in the CPU_PM_ENTER notifier, do we have a reason
to not do it in the do_armada_370_xp_cpu_suspend() function, and then
do_armada_38x_suspend() function respectively? Those functions are
already SoC-specific, so surely, they already know whether the resume
path should go through armada_370_xp_cpu_resume() or
armada_38x_cpu_resume(), no?

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 11/16] ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 15:37     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:37 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	devicetree, Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:52 +0200, Gregory CLEMENT wrote:
> The CA9 MPcore SoC Control block allows to do some configuration that
> the SoC could use for a specific use case. In most cases the defaults
> case is enough. However there is few exception: for cpuidle we need to
> use the CA9 MPcore Reset Control register.

I'd reword this to something like:

"""
The CA9 MPcore SoC Control block is a set of registers that allows to
configure certain internal aspects of the core blocks of the SoC
(Cortex-A9, L2 cache controller, etc.). In most cases, the default
values are fine so they aren't many reasons to touch those registers,
but there is one exception: to support cpuidle on Armada 38x, we need
to modify the value of the CA9 MPcore Reset Control register.

Therefore, this commit adds a new Device Tree binding for this hardware
block, and uses this new binding for the Armada 38x Device Tree file.

"""

> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> Cc: devicetree@vger.kernel.org
> ---
>  .../devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt | 14 ++++++++++++++
>  arch/arm/boot/dts/armada-38x.dtsi                          |  5 +++++
>  2 files changed, 19 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt b/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
> new file mode 100644
> index 000000000000..0a2df51ba560
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
> @@ -0,0 +1,14 @@
> +Marvell Armada 38x CA9 MPcore SoC Controller
> +============================================
> +
> +Required properties:
> +
> +- compatible: Should be "marvell,armada-380-mpcore-soc-ctrl".
> +
> +- reg: should be register base and length as documented in the

should be *the* register base and length

> +  datasheet for the CA9 MPcore SoC Control registers
> +
> +mpcore-soc-ctrl@20d20 {
> +	compatible = "marvell,armada-380-mpcore-soc-ctrl";
> +	reg = <0x20d20 0x6c>;
> +};
> diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
> index 689fa1a46728..242d0ecc99f3 100644
> --- a/arch/arm/boot/dts/armada-38x.dtsi
> +++ b/arch/arm/boot/dts/armada-38x.dtsi
> @@ -286,6 +286,11 @@
>  				reg = <0x20800 0x10>;
>  			};
>  
> +			mpcore-soc-ctrl@20d20 {
> +				compatible = "marvell,armada-380-mpcore-soc-ctrl";
> +				reg = <0x20d20 0x6c>;
> +			};
> +
>  			coherency-fabric@21010 {
>  				compatible = "marvell,armada-380-coherency-fabric";
>  				reg = <0x21010 0x1c>;

With those fixed:

Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 11/16] ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
@ 2014-06-30 15:37     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:52 +0200, Gregory CLEMENT wrote:
> The CA9 MPcore SoC Control block allows to do some configuration that
> the SoC could use for a specific use case. In most cases the defaults
> case is enough. However there is few exception: for cpuidle we need to
> use the CA9 MPcore Reset Control register.

I'd reword this to something like:

"""
The CA9 MPcore SoC Control block is a set of registers that allows to
configure certain internal aspects of the core blocks of the SoC
(Cortex-A9, L2 cache controller, etc.). In most cases, the default
values are fine so they aren't many reasons to touch those registers,
but there is one exception: to support cpuidle on Armada 38x, we need
to modify the value of the CA9 MPcore Reset Control register.

Therefore, this commit adds a new Device Tree binding for this hardware
block, and uses this new binding for the Armada 38x Device Tree file.

"""

> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> Cc: devicetree at vger.kernel.org
> ---
>  .../devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt | 14 ++++++++++++++
>  arch/arm/boot/dts/armada-38x.dtsi                          |  5 +++++
>  2 files changed, 19 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt b/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
> new file mode 100644
> index 000000000000..0a2df51ba560
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt
> @@ -0,0 +1,14 @@
> +Marvell Armada 38x CA9 MPcore SoC Controller
> +============================================
> +
> +Required properties:
> +
> +- compatible: Should be "marvell,armada-380-mpcore-soc-ctrl".
> +
> +- reg: should be register base and length as documented in the

should be *the* register base and length

> +  datasheet for the CA9 MPcore SoC Control registers
> +
> +mpcore-soc-ctrl at 20d20 {
> +	compatible = "marvell,armada-380-mpcore-soc-ctrl";
> +	reg = <0x20d20 0x6c>;
> +};
> diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
> index 689fa1a46728..242d0ecc99f3 100644
> --- a/arch/arm/boot/dts/armada-38x.dtsi
> +++ b/arch/arm/boot/dts/armada-38x.dtsi
> @@ -286,6 +286,11 @@
>  				reg = <0x20800 0x10>;
>  			};
>  
> +			mpcore-soc-ctrl at 20d20 {
> +				compatible = "marvell,armada-380-mpcore-soc-ctrl";
> +				reg = <0x20d20 0x6c>;
> +			};
> +
>  			coherency-fabric at 21010 {
>  				compatible = "marvell,armada-380-coherency-fabric";
>  				reg = <0x21010 0x1c>;

With those fixed:

Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-06-30 15:43     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:43 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:50 +0200, Gregory CLEMENT wrote:

>  /* No locking is needed because we only access per-CPU registers */
> -static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
> +static void mvebu_v7_pmsu_idle_prepare(bool deepidle, bool snoopdis)

I continue to find it odd to have more and more boolean arguments to a
function to indicate what the function should do. It often indicates
that the function should rather be split in smaller, fine-grained
functions. Another sad consequence of using booleans is that the call
sites of the functions can no longer be understood properly:

	mvebu_v7_pmsu_idle_prepare(false, true);
	mvebu_v7_pmsu_idle_prepare(true, true);
	mvebu_v7_pmsu_idle_prepare(false, false);

But oh well, it looks like it's the easiest solution here, and I admit
it's convenient to have one function to the entire business of
preparing for idle.

However, this change also badly conflicts with the CPU hotplug support
that I have sent, and which is already part of linux-next, and for
which Jason has sent a pull request to the arm-soc folks. See
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/tree/arch/arm/mach-mvebu/platsmp.c
for the usage of the armada_370_xp_pmsu_idle_enter() function.

Maybe your patch series should be based on mvebu/soc instead?

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
@ 2014-06-30 15:43     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:43 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:50 +0200, Gregory CLEMENT wrote:

>  /* No locking is needed because we only access per-CPU registers */
> -static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
> +static void mvebu_v7_pmsu_idle_prepare(bool deepidle, bool snoopdis)

I continue to find it odd to have more and more boolean arguments to a
function to indicate what the function should do. It often indicates
that the function should rather be split in smaller, fine-grained
functions. Another sad consequence of using booleans is that the call
sites of the functions can no longer be understood properly:

	mvebu_v7_pmsu_idle_prepare(false, true);
	mvebu_v7_pmsu_idle_prepare(true, true);
	mvebu_v7_pmsu_idle_prepare(false, false);

But oh well, it looks like it's the easiest solution here, and I admit
it's convenient to have one function to the entire business of
preparing for idle.

However, this change also badly conflicts with the CPU hotplug support
that I have sent, and which is already part of linux-next, and for
which Jason has sent a pull request to the arm-soc folks. See
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/tree/arch/arm/mach-mvebu/platsmp.c
for the usage of the armada_370_xp_pmsu_idle_enter() function.

Maybe your patch series should be based on mvebu/soc instead?

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x
  2014-06-27 13:22 ` Gregory CLEMENT
@ 2014-06-30 15:45   ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:45 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:41 +0200, Gregory CLEMENT wrote:

> This patch set adds the CPU Idle support for two mvebu SoCs: the
> Armada 370 and the Armada 38x. As there are common parts with the
> current support of cpuidle of the Armada XP. I made the code even more
> generic. Thanks to this change, adding a new SoC is now only done in
> the architecture specific part and we won't have to touch the cpuidle
> driver anymore for this.

I'd like to do some testing of this patch series, especially in big
endian situations. Do you have a Git repository where this version was
pushed?

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x
@ 2014-06-30 15:45   ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-06-30 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Fri, 27 Jun 2014 15:22:41 +0200, Gregory CLEMENT wrote:

> This patch set adds the CPU Idle support for two mvebu SoCs: the
> Armada 370 and the Armada 38x. As there are common parts with the
> current support of cpuidle of the Armada XP. I made the code even more
> generic. Thanks to this change, adding a new SoC is now only done in
> the architecture specific part and we won't have to touch the cpuidle
> driver anymore for this.

I'd like to do some testing of this patch series, especially in big
endian situations. Do you have a Git repository where this version was
pushed?

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x
  2014-06-30 15:45   ` Thomas Petazzoni
@ 2014-06-30 15:51     ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-30 15:51 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

On 30/06/2014 17:45, Thomas Petazzoni wrote:
> Gregory,
> 
> On Fri, 27 Jun 2014 15:22:41 +0200, Gregory CLEMENT wrote:
> 
>> This patch set adds the CPU Idle support for two mvebu SoCs: the
>> Armada 370 and the Armada 38x. As there are common parts with the
>> current support of cpuidle of the Armada XP. I made the code even more
>> generic. Thanks to this change, adding a new SoC is now only done in
>> the architecture specific part and we won't have to touch the cpuidle
>> driver anymore for this.
> 
> I'd like to do some testing of this patch series, especially in big
> endian situations. Do you have a Git repository where this version was
> pushed?

Yes sure, the branch CPU-Idle-mvebu-next-3.16-rc2-V1 on
https://github.com/MISL-EBU-System-SW/mainline-public.git

> 
> Thanks,
> 
> Thomas
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x
@ 2014-06-30 15:51     ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-06-30 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 30/06/2014 17:45, Thomas Petazzoni wrote:
> Gregory,
> 
> On Fri, 27 Jun 2014 15:22:41 +0200, Gregory CLEMENT wrote:
> 
>> This patch set adds the CPU Idle support for two mvebu SoCs: the
>> Armada 370 and the Armada 38x. As there are common parts with the
>> current support of cpuidle of the Armada XP. I made the code even more
>> generic. Thanks to this change, adding a new SoC is now only done in
>> the architecture specific part and we won't have to touch the cpuidle
>> driver anymore for this.
> 
> I'd like to do some testing of this patch series, especially in big
> endian situations. Do you have a Git repository where this version was
> pushed?

Yes sure, the branch CPU-Idle-mvebu-next-3.16-rc2-V1 on
https://github.com/MISL-EBU-System-SW/mainline-public.git

> 
> Thanks,
> 
> Thomas
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-07-01 11:46     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-01 11:46 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:44 +0200, Gregory CLEMENT wrote:

>  static void __iomem *system_controller_base;
> +static u32 system_controller_phys_base;
>  
>  struct mvebu_system_controller {
>  	u32 rstoutn_mask_offset;
> @@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
>  	writel(virt_to_phys(boot_addr), system_controller_base +
>  	       mvebu_sc->resume_boot_addr);
>  }
> +
> +u32 mvebu_system_controller_get_phys_addr(void)
> +{
> +	BUG_ON(system_controller_phys_base == NULL);

This rightfully generates a fairly strong warning at compile time:
you're comparing an u32 to NULL. It should be == 0 here.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
@ 2014-07-01 11:46     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-01 11:46 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:44 +0200, Gregory CLEMENT wrote:

>  static void __iomem *system_controller_base;
> +static u32 system_controller_phys_base;
>  
>  struct mvebu_system_controller {
>  	u32 rstoutn_mask_offset;
> @@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
>  	writel(virt_to_phys(boot_addr), system_controller_base +
>  	       mvebu_sc->resume_boot_addr);
>  }
> +
> +u32 mvebu_system_controller_get_phys_addr(void)
> +{
> +	BUG_ON(system_controller_phys_base == NULL);

This rightfully generates a fairly strong warning at compile time:
you're comparing an u32 to NULL. It should be == 0 here.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-07-01 14:34     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-01 14:34 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:43 +0200, Gregory CLEMENT wrote:

> +extern unsigned char mvebu_boot_wa_start;
> +extern unsigned char mvebu_boot_wa_end;
> +
> +void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
> +{
> +	void __iomem *sram_virt_base;
> +	u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
> +
> +	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
> +	mvebu_mbus_add_window_by_id(crypto_eng_id, CRYPT0_ENG_ATTR,
> +				SRAM_PHYS_BASE, SZ_64K);
> +	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
> +
> +
> +	memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
> +	/*
> +	 * The last word of the code copied in SRAM must contain the
> +	 * physical base address of the PMSU register
> +	 */
> +	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;

Contrary to what I said, use __raw_writel() and not writel() here, to
keep the native endianness of the system when writing the value:

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 9c56f8c..2b37e01 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -135,9 +135,11 @@ void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
        memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
        /*
         * The last word of the code copied in SRAM must contain the
-        * physical base address of the PMSU register
+        * physical base address of the PMSU register. We
+        * intentionally store this address in the native endianness
+        * of the system.
         */
-       *(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
+       __raw_writel(resume_addr_reg, sram_virt_base + code_len - 4);
 }

> +.global mvebu_boot_wa_start
> +.global mvebu_boot_wa_end
> +
> +/* The following code will be executed from SRAM */
> +ENTRY(mvebu_boot_wa_start)
> +mvebu_boot_wa_start:
> +/* use physical address of the boot address register register */
> +	adr     r0, 1f
> +	ldr     r0, [r0]
> +	ldr     r0, [r0]
> +	mov     pc, r0
> +/*
> + * the last word of this piece of code will be filled by the physical
> + * address of the boot address register just after being copied in SRAM
> + */
> +1:
> +	.long   .
> +mvebu_boot_wa_end:
> +ENDPROC(mvebu_boot_wa_end)

And this needs to be changed a bit to work properly in a big-endian
configuration:

diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index 15b823d..2f8b021 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -43,11 +43,14 @@ ENDPROC(armada_38x_cpu_resume)
 /* The following code will be executed from SRAM */
 ENTRY(mvebu_boot_wa_start)
 mvebu_boot_wa_start:
-/* use physical address of the boot address register register */
+ARM_BE8(setend be )                    @ go BE8 if entered LE
        adr     r0, 1f
-       ldr     r0, [r0]
-       ldr     r0, [r0]
-       mov     pc, r0
+       ldr     r0, [r0]                @ load the address of the
+                                       @ resume register
+       ldr     r0, [r0]                @ load the value in the
+                                       @ resume register
+ARM_BE8(rev    r0, r0)                 @ the value is stored LE
+       mov     pc, r0                  @ jump to this value

Note that the first ldr r0, [r0] does not need a rev r0, r0 because the
value is stored in the native endianness of the system thanks to the
__raw_writel() mentioned before. However, the second ldr r0, [r0] reads
the value in the Resume Address register, which is written in
little-endian by the writel() call in mvebu_pmsu_set_cpu_boot_addr().

Could you include this in your next iteration of the patches?

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
@ 2014-07-01 14:34     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-01 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:43 +0200, Gregory CLEMENT wrote:

> +extern unsigned char mvebu_boot_wa_start;
> +extern unsigned char mvebu_boot_wa_end;
> +
> +void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
> +{
> +	void __iomem *sram_virt_base;
> +	u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
> +
> +	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
> +	mvebu_mbus_add_window_by_id(crypto_eng_id, CRYPT0_ENG_ATTR,
> +				SRAM_PHYS_BASE, SZ_64K);
> +	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
> +
> +
> +	memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
> +	/*
> +	 * The last word of the code copied in SRAM must contain the
> +	 * physical base address of the PMSU register
> +	 */
> +	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;

Contrary to what I said, use __raw_writel() and not writel() here, to
keep the native endianness of the system when writing the value:

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 9c56f8c..2b37e01 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -135,9 +135,11 @@ void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
        memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
        /*
         * The last word of the code copied in SRAM must contain the
-        * physical base address of the PMSU register
+        * physical base address of the PMSU register. We
+        * intentionally store this address in the native endianness
+        * of the system.
         */
-       *(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
+       __raw_writel(resume_addr_reg, sram_virt_base + code_len - 4);
 }

> +.global mvebu_boot_wa_start
> +.global mvebu_boot_wa_end
> +
> +/* The following code will be executed from SRAM */
> +ENTRY(mvebu_boot_wa_start)
> +mvebu_boot_wa_start:
> +/* use physical address of the boot address register register */
> +	adr     r0, 1f
> +	ldr     r0, [r0]
> +	ldr     r0, [r0]
> +	mov     pc, r0
> +/*
> + * the last word of this piece of code will be filled by the physical
> + * address of the boot address register just after being copied in SRAM
> + */
> +1:
> +	.long   .
> +mvebu_boot_wa_end:
> +ENDPROC(mvebu_boot_wa_end)

And this needs to be changed a bit to work properly in a big-endian
configuration:

diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index 15b823d..2f8b021 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -43,11 +43,14 @@ ENDPROC(armada_38x_cpu_resume)
 /* The following code will be executed from SRAM */
 ENTRY(mvebu_boot_wa_start)
 mvebu_boot_wa_start:
-/* use physical address of the boot address register register */
+ARM_BE8(setend be )                    @ go BE8 if entered LE
        adr     r0, 1f
-       ldr     r0, [r0]
-       ldr     r0, [r0]
-       mov     pc, r0
+       ldr     r0, [r0]                @ load the address of the
+                                       @ resume register
+       ldr     r0, [r0]                @ load the value in the
+                                       @ resume register
+ARM_BE8(rev    r0, r0)                 @ the value is stored LE
+       mov     pc, r0                  @ jump to this value

Note that the first ldr r0, [r0] does not need a rev r0, r0 because the
value is stored in the native endianness of the system thanks to the
__raw_writel() mentioned before. However, the second ldr r0, [r0] reads
the value in the Resume Address register, which is written in
little-endian by the writel() call in mvebu_pmsu_set_cpu_boot_addr().

Could you include this in your next iteration of the patches?

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
  2014-06-27 13:22   ` Gregory CLEMENT
@ 2014-07-01 14:35     ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-01 14:35 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:56 +0200, Gregory CLEMENT wrote:

> +ENTRY(armada_38x_cpu_resume)
> +	/* do we need it for Armada 38x*/
> +ARM_BE8(setend	be )			@ go BE8 if entered LE

We logically needed this, but I've confirmed, and indeed it is really
needed for cpuidle to work properly on Armada 38x in big-endian
configuration.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
@ 2014-07-01 14:35     ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-01 14:35 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Fri, 27 Jun 2014 15:22:56 +0200, Gregory CLEMENT wrote:

> +ENTRY(armada_38x_cpu_resume)
> +	/* do we need it for Armada 38x*/
> +ARM_BE8(setend	be )			@ go BE8 if entered LE

We logically needed this, but I've confirmed, and indeed it is really
needed for cpuidle to work properly on Armada 38x in big-endian
configuration.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x
  2014-06-30 15:51     ` Gregory CLEMENT
@ 2014-07-01 14:38       ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-01 14:38 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Lior Amsalem, Andrew Lunn, Jason Cooper, Tawfik Bayouk, linux-pm,
	Daniel Lezcano, Rafael J. Wysocki, Nadav Haklai, Ezequiel Garcia,
	linux-arm-kernel, Sebastian Hesselbarth

Dear Gregory CLEMENT,

On Mon, 30 Jun 2014 17:51:39 +0200, Gregory CLEMENT wrote:

> > I'd like to do some testing of this patch series, especially in big
> > endian situations. Do you have a Git repository where this version was
> > pushed?
> 
> Yes sure, the branch CPU-Idle-mvebu-next-3.16-rc2-V1 on
> https://github.com/MISL-EBU-System-SW/mainline-public.git

Ok, I've tested the following cases:

 * Armada XP LE and BE: it shouldn't be affected by your patch series,
   and indeed, it works fine.

 * Armada 370 LE worked fine.

 * Armada 370 BE didn't work, I had to fix the code in
   pmsu.c/pmsu_ll.S. I already replied to the appropriate patch to
   indicate what was wrong.

 * Armada 375 LE worked fine. Armada 375 BE was also affected by the
   same issue as Armada 370 BE because they use the same work-around
   for the boot issue (Armada 375 Z1 of course, since Armada 375 A0 is
   not affected). With the fix added for big-endian, Armada 375 BE
   works again (i.e its SMP initialization works).

 * Armada 38x LE and BE worked fine (there was a completely unrelated
   issue in the SMP initialization of 38x in BE, I'll sent a patch
   shortly for this).

So all in all, in terms of testing, despite the minor fix for the BE
configuration, it looks good to me.

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x
@ 2014-07-01 14:38       ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-01 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Mon, 30 Jun 2014 17:51:39 +0200, Gregory CLEMENT wrote:

> > I'd like to do some testing of this patch series, especially in big
> > endian situations. Do you have a Git repository where this version was
> > pushed?
> 
> Yes sure, the branch CPU-Idle-mvebu-next-3.16-rc2-V1 on
> https://github.com/MISL-EBU-System-SW/mainline-public.git

Ok, I've tested the following cases:

 * Armada XP LE and BE: it shouldn't be affected by your patch series,
   and indeed, it works fine.

 * Armada 370 LE worked fine.

 * Armada 370 BE didn't work, I had to fix the code in
   pmsu.c/pmsu_ll.S. I already replied to the appropriate patch to
   indicate what was wrong.

 * Armada 375 LE worked fine. Armada 375 BE was also affected by the
   same issue as Armada 370 BE because they use the same work-around
   for the boot issue (Armada 375 Z1 of course, since Armada 375 A0 is
   not affected). With the fix added for big-endian, Armada 375 BE
   works again (i.e its SMP initialization works).

 * Armada 38x LE and BE worked fine (there was a completely unrelated
   issue in the SMP initialization of 38x in BE, I'll sent a patch
   shortly for this).

So all in all, in terms of testing, despite the minor fix for the BE
configuration, it looks good to me.

Thanks!

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
  2014-07-01 11:46     ` Thomas Petazzoni
@ 2014-07-01 15:02       ` Ezequiel Garcia
  -1 siblings, 0 replies; 120+ messages in thread
From: Ezequiel Garcia @ 2014-07-01 15:02 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Lior Amsalem, Andrew Lunn, Jason Cooper, Tawfik Bayouk, linux-pm,
	Daniel Lezcano, Rafael J. Wysocki, Nadav Haklai, Gregory CLEMENT,
	linux-arm-kernel, Sebastian Hesselbarth

On 01 Jul 01:46 PM, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Fri, 27 Jun 2014 15:22:44 +0200, Gregory CLEMENT wrote:
> 
> >  static void __iomem *system_controller_base;
> > +static u32 system_controller_phys_base;
> >  
> >  struct mvebu_system_controller {
> >  	u32 rstoutn_mask_offset;
> > @@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
> >  	writel(virt_to_phys(boot_addr), system_controller_base +
> >  	       mvebu_sc->resume_boot_addr);
> >  }
> > +
> > +u32 mvebu_system_controller_get_phys_addr(void)
> > +{
> > +	BUG_ON(system_controller_phys_base == NULL);
> 
> This rightfully generates a fairly strong warning at compile time:
> you're comparing an u32 to NULL. It should be == 0 here.
> 

Or a more readable BUG_ON(!system_controller_phys_base);
-- 
Ezequiel García, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
@ 2014-07-01 15:02       ` Ezequiel Garcia
  0 siblings, 0 replies; 120+ messages in thread
From: Ezequiel Garcia @ 2014-07-01 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 01 Jul 01:46 PM, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Fri, 27 Jun 2014 15:22:44 +0200, Gregory CLEMENT wrote:
> 
> >  static void __iomem *system_controller_base;
> > +static u32 system_controller_phys_base;
> >  
> >  struct mvebu_system_controller {
> >  	u32 rstoutn_mask_offset;
> > @@ -109,6 +110,13 @@ void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
> >  	writel(virt_to_phys(boot_addr), system_controller_base +
> >  	       mvebu_sc->resume_boot_addr);
> >  }
> > +
> > +u32 mvebu_system_controller_get_phys_addr(void)
> > +{
> > +	BUG_ON(system_controller_phys_base == NULL);
> 
> This rightfully generates a fairly strong warning at compile time:
> you're comparing an u32 to NULL. It should be == 0 here.
> 

Or a more readable BUG_ON(!system_controller_phys_base);
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

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

* Re: [PATCH 01/16] ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
  2014-06-30 12:16     ` Thomas Petazzoni
@ 2014-07-02 22:57       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-02 22:57 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,


>>  #include <linux/cpu_pm.h>
>> -#include <linux/kernel.h>
>>  #include <linux/init.h>
>> -#include <linux/of_address.h>
>> +#include <linux/kernel.h>
>>  #include <linux/io.h>
> 
> So, with your patch applied, if I'm correct, we will have:
> 
> #include <linux/init.h>
> #include <linux/kernel.h>
> #include <linux/io.h>
> 
> It seems like we're not yet alphabetically sorted here :)

Indeed, I will fix it


Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 01/16] ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
@ 2014-07-02 22:57       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-02 22:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,


>>  #include <linux/cpu_pm.h>
>> -#include <linux/kernel.h>
>>  #include <linux/init.h>
>> -#include <linux/of_address.h>
>> +#include <linux/kernel.h>
>>  #include <linux/io.h>
> 
> So, with your patch applied, if I'm correct, we will have:
> 
> #include <linux/init.h>
> #include <linux/kernel.h>
> #include <linux/io.h>
> 
> It seems like we're not yet alphabetically sorted here :)

Indeed, I will fix it


Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
  2014-06-30 12:40     ` Thomas Petazzoni
@ 2014-07-02 22:58       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-02 22:58 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,


> 
>> mvebu_boot_addr_wa().
> 
> I'm not sure the name of the function is appropriate, as we don't know
> what it is doing. Maybe mvebu_setup_boot_addr_wa() ?

I try to avoid too long name because then we have to do a lot of multiline
code. However I agree that this name is better, I will use it

> 
> Also, maybe your commit log should indicate that the workaround
> involves using the Crypto engine SRAM, which will help understanding
> the reference to the crypto engine in the code.
> 

OK

>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>  arch/arm/mach-mvebu/pmsu.c    | 31 +++++++++++++++++++++++++++++++
>>  arch/arm/mach-mvebu/pmsu.h    |  1 +
>>  arch/arm/mach-mvebu/pmsu_ll.S | 19 +++++++++++++++++++
>>  3 files changed, 51 insertions(+)
> 
> I don't really have a better suggestion, but the workaround doesn't
> seem to be related to the PMSU, so are pmsu.c and pmsu_ll.S really the
> right files to store this code?
> 
>>
>> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
>> index 5584d35b8e88..991560905ccc 100644
>> --- a/arch/arm/mach-mvebu/pmsu.c
>> +++ b/arch/arm/mach-mvebu/pmsu.c
>> @@ -22,6 +22,7 @@
>>  #include <linux/init.h>
>>  #include <linux/kernel.h>
>>  #include <linux/io.h>
>> +#include <linux/mbus.h>
>>  #include <linux/of_address.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/resource.h>
>> @@ -63,6 +64,14 @@ static void __iomem *pmsu_mp_base;
>>  #define L2C_NFABRIC_PM_CTL		    0x4
>>  #define L2C_NFABRIC_PM_CTL_PWR_DOWN		BIT(20)
>>  
>> +#define ARMADA_370_CRYPT0_ENG_ID	0x9
> 
> Not needed in this file, the MBus window target ID is passed as
> argument to the mvebu_boot_addr_wa() function.

OK
> 
>> +#define CRYPT0_ENG_ATTR	0x1
> 
> For consistency, I'd prefer to see this being passed as argument to
> mvebu_boot_addr_wa().

The attribute is the same, so why bother with it? If later we have a SoC
where this attribute can be different then I agree to add this argument.

> 
>> +#define SRAM_PHYS_BASE	    0xFFFF0000
>> +
>> +#define BOOTROM_BASE    0xFFF00000
>> +#define BOOTROM_SIZE    0x100000
>> +
>>  extern void ll_disable_coherency(void);
>>  extern void ll_enable_coherency(void);
>>  
>> @@ -85,6 +94,28 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
>>  		PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
>>  }
>>  
>> +extern unsigned char mvebu_boot_wa_start;
>> +extern unsigned char mvebu_boot_wa_end;
>> +
>> +void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
> 
> unsigned int crypto_eng_target ('unsigned int' is the type used by
> the mvebu-mbus API), and add unsigned int crypto_eng_attribute, to
> match the mvebu-mbus API. Also, void * seems more appropriate than u32
> for an address, maybe even void __iomem * since it's actually pointing
> to a memory-mapped register.

I was lazy for the resume_addr_reg and u32 was easier to use, but indeed
void __iomem * is better. I also agree for the other, I didn't notice it
was unsigned int instead of int.

> 
>> +{
>> +	void __iomem *sram_virt_base;
>> +	u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
>> +
>> +	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
>> +	mvebu_mbus_add_window_by_id(crypto_eng_id, CRYPT0_ENG_ATTR,
>> +				SRAM_PHYS_BASE, SZ_64K);
>> +	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
> 
> Maybe a return value check?

yes

> 
>> +
>> +
> 
> One too many new line.
> 
>> +	memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
>> +	/*
>> +	 * The last word of the code copied in SRAM must contain the
>> +	 * physical base address of the PMSU register
>> +	 */
>> +	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
> 
> Maybe instead:
> 
> 	writel(resume_addr_reg, sram_virt_base + code_len - 4);

Oh yes I forgot it was "iomaped"


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
@ 2014-07-02 22:58       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-02 22:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,


> 
>> mvebu_boot_addr_wa().
> 
> I'm not sure the name of the function is appropriate, as we don't know
> what it is doing. Maybe mvebu_setup_boot_addr_wa() ?

I try to avoid too long name because then we have to do a lot of multiline
code. However I agree that this name is better, I will use it

> 
> Also, maybe your commit log should indicate that the workaround
> involves using the Crypto engine SRAM, which will help understanding
> the reference to the crypto engine in the code.
> 

OK

>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>  arch/arm/mach-mvebu/pmsu.c    | 31 +++++++++++++++++++++++++++++++
>>  arch/arm/mach-mvebu/pmsu.h    |  1 +
>>  arch/arm/mach-mvebu/pmsu_ll.S | 19 +++++++++++++++++++
>>  3 files changed, 51 insertions(+)
> 
> I don't really have a better suggestion, but the workaround doesn't
> seem to be related to the PMSU, so are pmsu.c and pmsu_ll.S really the
> right files to store this code?
> 
>>
>> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
>> index 5584d35b8e88..991560905ccc 100644
>> --- a/arch/arm/mach-mvebu/pmsu.c
>> +++ b/arch/arm/mach-mvebu/pmsu.c
>> @@ -22,6 +22,7 @@
>>  #include <linux/init.h>
>>  #include <linux/kernel.h>
>>  #include <linux/io.h>
>> +#include <linux/mbus.h>
>>  #include <linux/of_address.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/resource.h>
>> @@ -63,6 +64,14 @@ static void __iomem *pmsu_mp_base;
>>  #define L2C_NFABRIC_PM_CTL		    0x4
>>  #define L2C_NFABRIC_PM_CTL_PWR_DOWN		BIT(20)
>>  
>> +#define ARMADA_370_CRYPT0_ENG_ID	0x9
> 
> Not needed in this file, the MBus window target ID is passed as
> argument to the mvebu_boot_addr_wa() function.

OK
> 
>> +#define CRYPT0_ENG_ATTR	0x1
> 
> For consistency, I'd prefer to see this being passed as argument to
> mvebu_boot_addr_wa().

The attribute is the same, so why bother with it? If later we have a SoC
where this attribute can be different then I agree to add this argument.

> 
>> +#define SRAM_PHYS_BASE	    0xFFFF0000
>> +
>> +#define BOOTROM_BASE    0xFFF00000
>> +#define BOOTROM_SIZE    0x100000
>> +
>>  extern void ll_disable_coherency(void);
>>  extern void ll_enable_coherency(void);
>>  
>> @@ -85,6 +94,28 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
>>  		PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
>>  }
>>  
>> +extern unsigned char mvebu_boot_wa_start;
>> +extern unsigned char mvebu_boot_wa_end;
>> +
>> +void mvebu_boot_addr_wa(int crypto_eng_id, u32 resume_addr_reg)
> 
> unsigned int crypto_eng_target ('unsigned int' is the type used by
> the mvebu-mbus API), and add unsigned int crypto_eng_attribute, to
> match the mvebu-mbus API. Also, void * seems more appropriate than u32
> for an address, maybe even void __iomem * since it's actually pointing
> to a memory-mapped register.

I was lazy for the resume_addr_reg and u32 was easier to use, but indeed
void __iomem * is better. I also agree for the other, I didn't notice it
was unsigned int instead of int.

> 
>> +{
>> +	void __iomem *sram_virt_base;
>> +	u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
>> +
>> +	mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
>> +	mvebu_mbus_add_window_by_id(crypto_eng_id, CRYPT0_ENG_ATTR,
>> +				SRAM_PHYS_BASE, SZ_64K);
>> +	sram_virt_base = ioremap(SRAM_PHYS_BASE, SZ_64K);
> 
> Maybe a return value check?

yes

> 
>> +
>> +
> 
> One too many new line.
> 
>> +	memcpy(sram_virt_base, &mvebu_boot_wa_start, code_len);
>> +	/*
>> +	 * The last word of the code copied in SRAM must contain the
>> +	 * physical base address of the PMSU register
>> +	 */
>> +	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
> 
> Maybe instead:
> 
> 	writel(resume_addr_reg, sram_virt_base + code_len - 4);

Oh yes I forgot it was "iomaped"


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
  2014-07-01 14:34     ` Thomas Petazzoni
@ 2014-07-02 22:58       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-02 22:58 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,


>> +	/*
>> +	 * The last word of the code copied in SRAM must contain the
>> +	 * physical base address of the PMSU register
>> +	 */
>> +	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
> 
> Contrary to what I said, use __raw_writel() and not writel() here, to
> keep the native endianness of the system when writing the value:

Ok


[...]
> --- a/arch/arm/mach-mvebu/pmsu_ll.S
> +++ b/arch/arm/mach-mvebu/pmsu_ll.S
> @@ -43,11 +43,14 @@ ENDPROC(armada_38x_cpu_resume)
>  /* The following code will be executed from SRAM */
>  ENTRY(mvebu_boot_wa_start)
>  mvebu_boot_wa_start:
> -/* use physical address of the boot address register register */
> +ARM_BE8(setend be )                    @ go BE8 if entered LE
>         adr     r0, 1f
> -       ldr     r0, [r0]
> -       ldr     r0, [r0]
> -       mov     pc, r0
> +       ldr     r0, [r0]                @ load the address of the
> +                                       @ resume register
> +       ldr     r0, [r0]                @ load the value in the
> +                                       @ resume register
> +ARM_BE8(rev    r0, r0)                 @ the value is stored LE
> +       mov     pc, r0                  @ jump to this value
> 
> Note that the first ldr r0, [r0] does not need a rev r0, r0 because the
> value is stored in the native endianness of the system thanks to the
> __raw_writel() mentioned before. However, the second ldr r0, [r0] reads
> the value in the Resume Address register, which is written in
> little-endian by the writel() call in mvebu_pmsu_set_cpu_boot_addr().
> 
> Could you include this in your next iteration of the patches?

Yes sure, and thanks again for having tested it in BE

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
@ 2014-07-02 22:58       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-02 22:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,


>> +	/*
>> +	 * The last word of the code copied in SRAM must contain the
>> +	 * physical base address of the PMSU register
>> +	 */
>> +	*(unsigned long *)(sram_virt_base + code_len - 4) = resume_addr_reg;
> 
> Contrary to what I said, use __raw_writel() and not writel() here, to
> keep the native endianness of the system when writing the value:

Ok


[...]
> --- a/arch/arm/mach-mvebu/pmsu_ll.S
> +++ b/arch/arm/mach-mvebu/pmsu_ll.S
> @@ -43,11 +43,14 @@ ENDPROC(armada_38x_cpu_resume)
>  /* The following code will be executed from SRAM */
>  ENTRY(mvebu_boot_wa_start)
>  mvebu_boot_wa_start:
> -/* use physical address of the boot address register register */
> +ARM_BE8(setend be )                    @ go BE8 if entered LE
>         adr     r0, 1f
> -       ldr     r0, [r0]
> -       ldr     r0, [r0]
> -       mov     pc, r0
> +       ldr     r0, [r0]                @ load the address of the
> +                                       @ resume register
> +       ldr     r0, [r0]                @ load the value in the
> +                                       @ resume register
> +ARM_BE8(rev    r0, r0)                 @ the value is stored LE
> +       mov     pc, r0                  @ jump to this value
> 
> Note that the first ldr r0, [r0] does not need a rev r0, r0 because the
> value is stored in the native endianness of the system thanks to the
> __raw_writel() mentioned before. However, the second ldr r0, [r0] reads
> the value in the Resume Address register, which is written in
> little-endian by the writel() call in mvebu_pmsu_set_cpu_boot_addr().
> 
> Could you include this in your next iteration of the patches?

Yes sure, and thanks again for having tested it in BE

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
  2014-07-02 22:58       ` Gregory CLEMENT
@ 2014-07-03  7:16         ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-03  7:16 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Gregory,

On Thu, 03 Jul 2014 00:58:22 +0200, Gregory CLEMENT wrote:

> >> +#define CRYPT0_ENG_ATTR	0x1
> > 
> > For consistency, I'd prefer to see this being passed as argument to
> > mvebu_boot_addr_wa().
> 
> The attribute is the same, so why bother with it? If later we have a SoC
> where this attribute can be different then I agree to add this argument.

Simply for consistency. MBus windows are defined by their target and
attribute values, so it makes sense to always pass both these values,
even if for the existing cases the attribute is for now always 0x1.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around
@ 2014-07-03  7:16         ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-03  7:16 UTC (permalink / raw)
  To: linux-arm-kernel

Gregory,

On Thu, 03 Jul 2014 00:58:22 +0200, Gregory CLEMENT wrote:

> >> +#define CRYPT0_ENG_ATTR	0x1
> > 
> > For consistency, I'd prefer to see this being passed as argument to
> > mvebu_boot_addr_wa().
> 
> The attribute is the same, so why bother with it? If later we have a SoC
> where this attribute can be different then I agree to add this argument.

Simply for consistency. MBus windows are defined by their target and
attribute values, so it makes sense to always pass both these values,
even if for the existing cases the attribute is for now always 0x1.

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
  2014-06-30 12:46     ` Thomas Petazzoni
@ 2014-07-03  8:39       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  8:39 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,

On 30/06/2014 14:46, Thomas Petazzoni wrote:
> Gregory,
> 
> I'm not sure that the best approach to solve this problem. Instead,
> maybe the system-controller.c code should set up the boot address
> workaround on Armada 375. Since the workaround on 375 is really related
> to setting the boot address which is done by the system controller,
> maybe the initialization of the workaround belongs in
> system-controller.c ?

So moving the workaround into mvebu_system_controller_set_cpu_boot_addr()
should be the thing to do.


Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
@ 2014-07-03  8:39       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

On 30/06/2014 14:46, Thomas Petazzoni wrote:
> Gregory,
> 
> I'm not sure that the best approach to solve this problem. Instead,
> maybe the system-controller.c code should set up the boot address
> workaround on Armada 375. Since the workaround on 375 is really related
> to setting the boot address which is done by the system controller,
> maybe the initialization of the workaround belongs in
> system-controller.c ?

So moving the workaround into mvebu_system_controller_set_cpu_boot_addr()
should be the thing to do.


Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370
  2014-06-30 12:50     ` Thomas Petazzoni
@ 2014-07-03  8:44       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  8:44 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,

On 30/06/2014 14:50, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Fri, 27 Jun 2014 15:22:46 +0200, Gregory CLEMENT wrote:
>> On Armada 370, there is "a slow exit process from the deep idle state
>> due to heavy L1/L2 cache cleanup operations performed by the BootROM
>> software" (cf errata GL-BootROM-10). To avoid this, we replace the
>> restart code of the BootROM by a simple jump to the boot address. Then
>> the code located at this boot address will take care of the
>> initialization.
>>
>> For this purpose, we use the common function mvebu_boot_addr_wa()
>> introduced in the previous commit.
> 
> "in the previous commit" would make sense if the commit immediately
> before this one in the series was the one you would be referencing. But
> that's not the case here, so it should be either: "introduced in one of
> the previous commits", or better "introduced in commit <title of the
> commit>".

Yes it should have been the previous commit at a point of development
and it was moved during a rebase. Using the title of the commit is more
reliable indeed.

> 
>>  #define PMSU_BASE_OFFSET    0x100
>>  #define PMSU_REG_SIZE	    0x1000
>> @@ -77,6 +76,9 @@ extern void ll_enable_coherency(void);
>>  
>>  extern void armada_370_xp_cpu_resume(void);
>>  
>> +static unsigned long pmsu_mp_phys_base;
> 
> phys_addr_t.

OK


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370
@ 2014-07-03  8:44       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  8:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

On 30/06/2014 14:50, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Fri, 27 Jun 2014 15:22:46 +0200, Gregory CLEMENT wrote:
>> On Armada 370, there is "a slow exit process from the deep idle state
>> due to heavy L1/L2 cache cleanup operations performed by the BootROM
>> software" (cf errata GL-BootROM-10). To avoid this, we replace the
>> restart code of the BootROM by a simple jump to the boot address. Then
>> the code located at this boot address will take care of the
>> initialization.
>>
>> For this purpose, we use the common function mvebu_boot_addr_wa()
>> introduced in the previous commit.
> 
> "in the previous commit" would make sense if the commit immediately
> before this one in the series was the one you would be referencing. But
> that's not the case here, so it should be either: "introduced in one of
> the previous commits", or better "introduced in commit <title of the
> commit>".

Yes it should have been the previous commit at a point of development
and it was moved during a rebase. Using the title of the commit is more
reliable indeed.

> 
>>  #define PMSU_BASE_OFFSET    0x100
>>  #define PMSU_REG_SIZE	    0x1000
>> @@ -77,6 +76,9 @@ extern void ll_enable_coherency(void);
>>  
>>  extern void armada_370_xp_cpu_resume(void);
>>  
>> +static unsigned long pmsu_mp_phys_base;
> 
> phys_addr_t.

OK


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 06/16] ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
  2014-06-30 12:57     ` Thomas Petazzoni
@ 2014-07-03  8:47       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  8:47 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

On 30/06/2014 14:57, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Fri, 27 Jun 2014 15:22:47 +0200, Gregory CLEMENT wrote:
>> Actually most of the function related to the PMSU are not specific to
>> the Armada 370 or Armada XP SoCs, but can also be used for most of the
>> other mvebu ARMv7 SoCs.
>>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>  arch/arm/mach-mvebu/pmsu.c | 40 ++++++++++++++++++++--------------------
>>  1 file changed, 20 insertions(+), 20 deletions(-)
> 
> I'm fine on the principle, but this badly conflicts with the PMSU
> changes I've made to support CPU hotplug, which are already in
> linux-next. See
> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/log/arch/arm/mach-mvebu/pmsu.c.
> 
>>  /* No locking is needed because we only access per-CPU registers */
>> -void armada_370_xp_pmsu_idle_prepare(bool deepidle)
>> +static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
> 
> Also, note here that you're not only renaming, but also adding the
> 'static' qualifier. This is already done in linux-next by
> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/arch/arm/mach-mvebu/pmsu.c?id=adb1d99384c7480886153a97d2ea22e9c0d2e053,
> but the function is anyway renamed in
> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/arch/arm/mach-mvebu/pmsu.c?id=bbb92284b6c821e9434223d437fbd10b8a24c294
> as a preparation for CPU hotplug support.

I am rebasing this series onto mvebu/fixes and mvebu/soc.
I take care of all your remark during this rebasing.


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 06/16] ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
@ 2014-07-03  8:47       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  8:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 30/06/2014 14:57, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Fri, 27 Jun 2014 15:22:47 +0200, Gregory CLEMENT wrote:
>> Actually most of the function related to the PMSU are not specific to
>> the Armada 370 or Armada XP SoCs, but can also be used for most of the
>> other mvebu ARMv7 SoCs.
>>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>> ---
>>  arch/arm/mach-mvebu/pmsu.c | 40 ++++++++++++++++++++--------------------
>>  1 file changed, 20 insertions(+), 20 deletions(-)
> 
> I'm fine on the principle, but this badly conflicts with the PMSU
> changes I've made to support CPU hotplug, which are already in
> linux-next. See
> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/log/arch/arm/mach-mvebu/pmsu.c.
> 
>>  /* No locking is needed because we only access per-CPU registers */
>> -void armada_370_xp_pmsu_idle_prepare(bool deepidle)
>> +static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
> 
> Also, note here that you're not only renaming, but also adding the
> 'static' qualifier. This is already done in linux-next by
> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/arch/arm/mach-mvebu/pmsu.c?id=adb1d99384c7480886153a97d2ea22e9c0d2e053,
> but the function is anyway renamed in
> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/arch/arm/mach-mvebu/pmsu.c?id=bbb92284b6c821e9434223d437fbd10b8a24c294
> as a preparation for CPU hotplug support.

I am rebasing this series onto mvebu/fixes and mvebu/soc.
I take care of all your remark during this rebasing.


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
  2014-06-30 14:07     ` Thomas Petazzoni
@ 2014-07-03  8:54       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  8:54 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,

	struct device_node *np;
>> +	const struct of_device_id *match;
>> +
>> +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
>> +					&match);
> 
> I'm not sure I like using of_find_matching_node_and_match() on the
> entire tree to find the root node compatible string. Wouldn't it be
> simpler and shorter to just do:
> 
> 	if (of_machine_is_compatible("marvell,armadaxp"))
> 		ret = armadaxp_cpuidle_init();
> 	else if (of_machine_is_compatible("marvell,armada370"))
> 		ret = armada370_cpuidle_init();
> 	else if (of_machine_is_compaitble("marvell,armada380"))
> 		ret = armada38x_cpuidle_init();
> 
> 	if (ret)
> 		return ret;

Indeed, as I don't use any resource from the device tree here, using
of_find_matching_node_and_match is overkill. And your alternative
will be enough.

> 
> Also, using a boolean to return a success/error status is not the
> kernel way of doing things, you should use an int instead and use
> proper error codes or return 0 on success.

OK


Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic
@ 2014-07-03  8:54       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  8:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

	struct device_node *np;
>> +	const struct of_device_id *match;
>> +
>> +	np = of_find_matching_node_and_match(NULL, of_cpuidle_table,
>> +					&match);
> 
> I'm not sure I like using of_find_matching_node_and_match() on the
> entire tree to find the root node compatible string. Wouldn't it be
> simpler and shorter to just do:
> 
> 	if (of_machine_is_compatible("marvell,armadaxp"))
> 		ret = armadaxp_cpuidle_init();
> 	else if (of_machine_is_compatible("marvell,armada370"))
> 		ret = armada370_cpuidle_init();
> 	else if (of_machine_is_compaitble("marvell,armada380"))
> 		ret = armada38x_cpuidle_init();
> 
> 	if (ret)
> 		return ret;

Indeed, as I don't use any resource from the device tree here, using
of_find_matching_node_and_match is overkill. And your alternative
will be enough.

> 
> Also, using a boolean to return a success/error status is not the
> kernel way of doing things, you should use an int instead and use
> proper error codes or return 0 on success.

OK


Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 08/16] ARM: mvebu: Use a local variable to store the resume address
  2014-06-30 15:09     ` Thomas Petazzoni
@ 2014-07-03  9:24       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  9:24 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Lior Amsalem, Andrew Lunn, Jason Cooper, Tawfik Bayouk, linux-pm,
	Daniel Lezcano, Rafael J. Wysocki, Nadav Haklai, Ezequiel Garcia,
	linux-arm-kernel, Sebastian Hesselbarth

Hi Thomas,

On 30/06/2014 17:09, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Fri, 27 Jun 2014 15:22:49 +0200, Gregory CLEMENT wrote:
> 
>> +static void *mvebu_cpu_resume;
>> +
>>  static struct platform_device mvebu_v7_cpuidle_device = {
>>  	.name = "cpuidle-armada-370-xp",
>>  };
>> @@ -281,7 +283,7 @@ static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
>>  {
>>  	if (action == CPU_PM_ENTER) {
>>  		unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
>> -		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
>> +		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cpu_resume);
> 
> Instead of doing this in the CPU_PM_ENTER notifier, do we have a reason
> to not do it in the do_armada_370_xp_cpu_suspend() function, and then
> do_armada_38x_suspend() function respectively? Those functions are
> already SoC-specific, so surely, they already know whether the resume
> path should go through armada_370_xp_cpu_resume() or
> armada_38x_cpu_resume(), no?

Now that all this code is also part of pmsu and no more in the cpu dile driver.
It should be possible. Let me see what it implies about the path code.

Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 08/16] ARM: mvebu: Use a local variable to store the resume address
@ 2014-07-03  9:24       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03  9:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

On 30/06/2014 17:09, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Fri, 27 Jun 2014 15:22:49 +0200, Gregory CLEMENT wrote:
> 
>> +static void *mvebu_cpu_resume;
>> +
>>  static struct platform_device mvebu_v7_cpuidle_device = {
>>  	.name = "cpuidle-armada-370-xp",
>>  };
>> @@ -281,7 +283,7 @@ static int mvebu_v7_cpu_pm_notify(struct notifier_block *self,
>>  {
>>  	if (action == CPU_PM_ENTER) {
>>  		unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
>> -		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
>> +		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cpu_resume);
> 
> Instead of doing this in the CPU_PM_ENTER notifier, do we have a reason
> to not do it in the do_armada_370_xp_cpu_suspend() function, and then
> do_armada_38x_suspend() function respectively? Those functions are
> already SoC-specific, so surely, they already know whether the resume
> path should go through armada_370_xp_cpu_resume() or
> armada_38x_cpu_resume(), no?

Now that all this code is also part of pmsu and no more in the cpu dile driver.
It should be possible. Let me see what it implies about the path code.

Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
  2014-07-03  8:39       ` Gregory CLEMENT
@ 2014-07-03  9:25         ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-03  9:25 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Thu, 03 Jul 2014 10:39:52 +0200, Gregory CLEMENT wrote:

> > I'm not sure that the best approach to solve this problem. Instead,
> > maybe the system-controller.c code should set up the boot address
> > workaround on Armada 375. Since the workaround on 375 is really related
> > to setting the boot address which is done by the system controller,
> > maybe the initialization of the workaround belongs in
> > system-controller.c ?
> 
> So moving the workaround into mvebu_system_controller_set_cpu_boot_addr()
> should be the thing to do.

Except that mvebu_system_controller_set_cpu_boot_addr() is called
multiple times during the system execution, while you want the
workaround to be initialized once. And we surely don't really want a
static variable in there to test if the workaround has already been
initialized or not.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
@ 2014-07-03  9:25         ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-03  9:25 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Thu, 03 Jul 2014 10:39:52 +0200, Gregory CLEMENT wrote:

> > I'm not sure that the best approach to solve this problem. Instead,
> > maybe the system-controller.c code should set up the boot address
> > workaround on Armada 375. Since the workaround on 375 is really related
> > to setting the boot address which is done by the system controller,
> > maybe the initialization of the workaround belongs in
> > system-controller.c ?
> 
> So moving the workaround into mvebu_system_controller_set_cpu_boot_addr()
> should be the thing to do.

Except that mvebu_system_controller_set_cpu_boot_addr() is called
multiple times during the system execution, while you want the
workaround to be initialized once. And we surely don't really want a
static variable in there to test if the workaround has already been
initialized or not.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
  2014-07-03  9:25         ` Thomas Petazzoni
@ 2014-07-03 10:07           ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 10:07 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,

On 03/07/2014 11:25, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Thu, 03 Jul 2014 10:39:52 +0200, Gregory CLEMENT wrote:
> 
>>> I'm not sure that the best approach to solve this problem. Instead,
>>> maybe the system-controller.c code should set up the boot address
>>> workaround on Armada 375. Since the workaround on 375 is really related
>>> to setting the boot address which is done by the system controller,
>>> maybe the initialization of the workaround belongs in
>>> system-controller.c ?
>>
>> So moving the workaround into mvebu_system_controller_set_cpu_boot_addr()
>> should be the thing to do.
> 
> Except that mvebu_system_controller_set_cpu_boot_addr() is called
> multiple times during the system execution, while you want the
> workaround to be initialized once. And we surely don't really want a
> static variable in there to test if the workaround has already been
> initialized or not.

Actually mvebu_system_controller_set_cpu_boot_addr()à is called only in
mvebu_cortex_a9_boot_secondary() just after the call to mvebu_boot_addr_wa().

So it won't change anything. Moreover the call to mvebu_cortex_a9_boot_secondary()
is not expected to be done too often  during the system execution.

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register
@ 2014-07-03 10:07           ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 10:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

On 03/07/2014 11:25, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
> 
> On Thu, 03 Jul 2014 10:39:52 +0200, Gregory CLEMENT wrote:
> 
>>> I'm not sure that the best approach to solve this problem. Instead,
>>> maybe the system-controller.c code should set up the boot address
>>> workaround on Armada 375. Since the workaround on 375 is really related
>>> to setting the boot address which is done by the system controller,
>>> maybe the initialization of the workaround belongs in
>>> system-controller.c ?
>>
>> So moving the workaround into mvebu_system_controller_set_cpu_boot_addr()
>> should be the thing to do.
> 
> Except that mvebu_system_controller_set_cpu_boot_addr() is called
> multiple times during the system execution, while you want the
> workaround to be initialized once. And we surely don't really want a
> static variable in there to test if the workaround has already been
> initialized or not.

Actually mvebu_system_controller_set_cpu_boot_addr()? is called only in
mvebu_cortex_a9_boot_secondary() just after the call to mvebu_boot_addr_wa().

So it won't change anything. Moreover the call to mvebu_cortex_a9_boot_secondary()
is not expected to be done too often  during the system execution.

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
  2014-06-30 15:43     ` Thomas Petazzoni
@ 2014-07-03 12:50       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 12:50 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,

>>  /* No locking is needed because we only access per-CPU registers */
>> -static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
>> +static void mvebu_v7_pmsu_idle_prepare(bool deepidle, bool snoopdis)
> 
> I continue to find it odd to have more and more boolean arguments to a
> function to indicate what the function should do. It often indicates
> that the function should rather be split in smaller, fine-grained
> functions. Another sad consequence of using booleans is that the call
> sites of the functions can no longer be understood properly:
> 
> 	mvebu_v7_pmsu_idle_prepare(false, true);
> 	mvebu_v7_pmsu_idle_prepare(true, true);
> 	mvebu_v7_pmsu_idle_prepare(false, false);
> 
> But oh well, it looks like it's the easiest solution here, and I admit
> it's convenient to have one function to the entire business of
> preparing for idle.

Maybe we can use flags, hence we use only one arguments, it became extensible,
and more readable too. Something like

#define PMSU_IDLE_NO_FLAG 0
#define PMSU_IDLE_DEEPIDLE BIT(0)
#define PMSU_IDLE_SNOOPDIS BIT(1)

then we can have:
mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_SNOOPDIS);
mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_DEEPIDLE | PMSU_IDLE_SNOOPDIS);
mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_NO_FLAG);

static void mvebu_v7_pmsu_idle_prepare(u32 flags)

Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
@ 2014-07-03 12:50       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

>>  /* No locking is needed because we only access per-CPU registers */
>> -static void mvebu_v7_pmsu_idle_prepare(bool deepidle)
>> +static void mvebu_v7_pmsu_idle_prepare(bool deepidle, bool snoopdis)
> 
> I continue to find it odd to have more and more boolean arguments to a
> function to indicate what the function should do. It often indicates
> that the function should rather be split in smaller, fine-grained
> functions. Another sad consequence of using booleans is that the call
> sites of the functions can no longer be understood properly:
> 
> 	mvebu_v7_pmsu_idle_prepare(false, true);
> 	mvebu_v7_pmsu_idle_prepare(true, true);
> 	mvebu_v7_pmsu_idle_prepare(false, false);
> 
> But oh well, it looks like it's the easiest solution here, and I admit
> it's convenient to have one function to the entire business of
> preparing for idle.

Maybe we can use flags, hence we use only one arguments, it became extensible,
and more readable too. Something like

#define PMSU_IDLE_NO_FLAG 0
#define PMSU_IDLE_DEEPIDLE BIT(0)
#define PMSU_IDLE_SNOOPDIS BIT(1)

then we can have:
mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_SNOOPDIS);
mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_DEEPIDLE | PMSU_IDLE_SNOOPDIS);
mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_NO_FLAG);

static void mvebu_v7_pmsu_idle_prepare(u32 flags)

Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 11/16] ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
  2014-06-30 15:37     ` Thomas Petazzoni
@ 2014-07-03 12:51       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 12:51 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	devicetree, Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,


> On Fri, 27 Jun 2014 15:22:52 +0200, Gregory CLEMENT wrote:
>> The CA9 MPcore SoC Control block allows to do some configuration that
>> the SoC could use for a specific use case. In most cases the defaults
>> case is enough. However there is few exception: for cpuidle we need to
>> use the CA9 MPcore Reset Control register.
> 
> I'd reword this to something like:
> 
> """
> The CA9 MPcore SoC Control block is a set of registers that allows to
> configure certain internal aspects of the core blocks of the SoC
> (Cortex-A9, L2 cache controller, etc.). In most cases, the default
> values are fine so they aren't many reasons to touch those registers,
> but there is one exception: to support cpuidle on Armada 38x, we need
> to modify the value of the CA9 MPcore Reset Control register.
> 
> Therefore, this commit adds a new Device Tree binding for this hardware
> block, and uses this new binding for the Armada 38x Device Tree file.
> 
> """

[...]

>> +- reg: should be register base and length as documented in the
> 
> should be *the* register base and length
> 
			reg = <0x21010 0x1c>;
> 
> With those fixed:
> 
> Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>


I will apply your change.

Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 11/16] ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
@ 2014-07-03 12:51       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 12:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,


> On Fri, 27 Jun 2014 15:22:52 +0200, Gregory CLEMENT wrote:
>> The CA9 MPcore SoC Control block allows to do some configuration that
>> the SoC could use for a specific use case. In most cases the defaults
>> case is enough. However there is few exception: for cpuidle we need to
>> use the CA9 MPcore Reset Control register.
> 
> I'd reword this to something like:
> 
> """
> The CA9 MPcore SoC Control block is a set of registers that allows to
> configure certain internal aspects of the core blocks of the SoC
> (Cortex-A9, L2 cache controller, etc.). In most cases, the default
> values are fine so they aren't many reasons to touch those registers,
> but there is one exception: to support cpuidle on Armada 38x, we need
> to modify the value of the CA9 MPcore Reset Control register.
> 
> Therefore, this commit adds a new Device Tree binding for this hardware
> block, and uses this new binding for the Armada 38x Device Tree file.
> 
> """

[...]

>> +- reg: should be register base and length as documented in the
> 
> should be *the* register base and length
> 
			reg = <0x21010 0x1c>;
> 
> With those fixed:
> 
> Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>


I will apply your change.

Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
  2014-07-03 12:50       ` Gregory CLEMENT
@ 2014-07-03 12:55         ` Thomas Petazzoni
  -1 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-03 12:55 UTC (permalink / raw)
  To: Gregory CLEMENT
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Dear Gregory CLEMENT,

On Thu, 03 Jul 2014 14:50:22 +0200, Gregory CLEMENT wrote:

> Maybe we can use flags, hence we use only one arguments, it became extensible,
> and more readable too. Something like
> 
> #define PMSU_IDLE_NO_FLAG 0
> #define PMSU_IDLE_DEEPIDLE BIT(0)
> #define PMSU_IDLE_SNOOPDIS BIT(1)
> 
> then we can have:
> mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_SNOOPDIS);
> mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_DEEPIDLE | PMSU_IDLE_SNOOPDIS);
> mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_NO_FLAG);
> 
> static void mvebu_v7_pmsu_idle_prepare(u32 flags)

Yes, seems a good idea to me. Used "unsigned int" as the type for the
flags argument, and maybe use PMSU_IDLE_NORMAL for 0 instead of NO_FLAG.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
@ 2014-07-03 12:55         ` Thomas Petazzoni
  0 siblings, 0 replies; 120+ messages in thread
From: Thomas Petazzoni @ 2014-07-03 12:55 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Gregory CLEMENT,

On Thu, 03 Jul 2014 14:50:22 +0200, Gregory CLEMENT wrote:

> Maybe we can use flags, hence we use only one arguments, it became extensible,
> and more readable too. Something like
> 
> #define PMSU_IDLE_NO_FLAG 0
> #define PMSU_IDLE_DEEPIDLE BIT(0)
> #define PMSU_IDLE_SNOOPDIS BIT(1)
> 
> then we can have:
> mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_SNOOPDIS);
> mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_DEEPIDLE | PMSU_IDLE_SNOOPDIS);
> mvebu_v7_pmsu_idle_prepare(PMSU_IDLE_NO_FLAG);
> 
> static void mvebu_v7_pmsu_idle_prepare(u32 flags)

Yes, seems a good idea to me. Used "unsigned int" as the type for the
flags argument, and maybe use PMSU_IDLE_NORMAL for 0 instead of NO_FLAG.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

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

* Re: [PATCH 12/16] cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
  2014-06-30 13:28     ` Thomas Petazzoni
@ 2014-07-03 13:08       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 13:08 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,


> On Fri, 27 Jun 2014 15:22:53 +0200, Gregory CLEMENT wrote:
>> Actually this driver will be able to manage the cpuidle for more SoCs
>> that Armada 370 ad XP. It will support Armada 38x and potentially
>> Armada 375. This patch change the names accordingly to this behavior.
> 
> I think the last sentence should rather be something like: "This patch
> renames the driver as well as the functions and variables used in the
> driver".
> 
> I would also specifically mention the renaming of the driver that
> requires changing the pmsu.c file. It is worth mentioning that this
> rename, touching both drivers/cpuidle and arch/arm/mach-mvebu, may
> require some special handling in terms of patch merging (the patch
> mainly touches drivers/cpuidle so it should theoretically go through
> the cpuidle maintainer, but since the pmsu.c file is touched a lot by
> other patches, there will probably be lots of conflicts if this patch
> goes through the cpuidle tree). Surely something to mention as a
> comment in the patch, maybe to get the Acked-by of the cpuidle people
> and merge things through the mvebu and arm-soc trees.

I mentioned it in the cover letter but not with all the details.

> 
>> -config ARM_ARMADA_370_XP_CPUIDLE
>> -	bool "CPU Idle Driver for Armada 370/XP family processors"
>> +config ARM_MVEBU_V7_CPUIDLE
>> +	bool "CPU Idle Driver for mvebu v7 family processors"
> 
> Actually, what worries me a bit of that Dove is a ARMv7 processor of
> the mvebu family, but which is not using this cpuidle driver. Do you
> expect Dove to be able to use this driver in the future?

Dove is also capable to go in deep idle mode as the other. The driver is
now very generic all the SoC related code are not in the driver, so it
would be possible. An argument against it, is that Armada 370, 38x and XP
all use the PMSU manage the deep idle mode, wheres Dove use an other set
of register.

> 
>>  	depends on ARCH_MVEBU
>>  	help
>> -	  Select this to enable cpuidle on Armada 370/XP processors.
>> +	  Select this to enable cpuidle on Armada 370, 385 and XP processors.
> 
> 385 -> 38x, because 380 and 385 are both capable of using this driver.

OK
> 
>> diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c
>> deleted file mode 100644
>> index a5fba0287bfb..000000000000
>> --- a/drivers/cpuidle/cpuidle-armada-370-xp.c
>> +++ /dev/null
> 
> You haven't enabled rename detection in git? Or git isn't detecting the
> rename because of the number of changes in the file?

I am not aware of this kind of configuration, internally for git I think it is
the same thing, it is only the way he exposed this to the user that can be changed.
However, it is true that I didn't use the -M flag with format-patch.

I will use it next time, because there also some change in the driver itself, it was
mostly something like s/armada_370_xp/mvebu_v7/


Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 12/16] cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
@ 2014-07-03 13:08       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 13:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,


> On Fri, 27 Jun 2014 15:22:53 +0200, Gregory CLEMENT wrote:
>> Actually this driver will be able to manage the cpuidle for more SoCs
>> that Armada 370 ad XP. It will support Armada 38x and potentially
>> Armada 375. This patch change the names accordingly to this behavior.
> 
> I think the last sentence should rather be something like: "This patch
> renames the driver as well as the functions and variables used in the
> driver".
> 
> I would also specifically mention the renaming of the driver that
> requires changing the pmsu.c file. It is worth mentioning that this
> rename, touching both drivers/cpuidle and arch/arm/mach-mvebu, may
> require some special handling in terms of patch merging (the patch
> mainly touches drivers/cpuidle so it should theoretically go through
> the cpuidle maintainer, but since the pmsu.c file is touched a lot by
> other patches, there will probably be lots of conflicts if this patch
> goes through the cpuidle tree). Surely something to mention as a
> comment in the patch, maybe to get the Acked-by of the cpuidle people
> and merge things through the mvebu and arm-soc trees.

I mentioned it in the cover letter but not with all the details.

> 
>> -config ARM_ARMADA_370_XP_CPUIDLE
>> -	bool "CPU Idle Driver for Armada 370/XP family processors"
>> +config ARM_MVEBU_V7_CPUIDLE
>> +	bool "CPU Idle Driver for mvebu v7 family processors"
> 
> Actually, what worries me a bit of that Dove is a ARMv7 processor of
> the mvebu family, but which is not using this cpuidle driver. Do you
> expect Dove to be able to use this driver in the future?

Dove is also capable to go in deep idle mode as the other. The driver is
now very generic all the SoC related code are not in the driver, so it
would be possible. An argument against it, is that Armada 370, 38x and XP
all use the PMSU manage the deep idle mode, wheres Dove use an other set
of register.

> 
>>  	depends on ARCH_MVEBU
>>  	help
>> -	  Select this to enable cpuidle on Armada 370/XP processors.
>> +	  Select this to enable cpuidle on Armada 370, 385 and XP processors.
> 
> 385 -> 38x, because 380 and 385 are both capable of using this driver.

OK
> 
>> diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c
>> deleted file mode 100644
>> index a5fba0287bfb..000000000000
>> --- a/drivers/cpuidle/cpuidle-armada-370-xp.c
>> +++ /dev/null
> 
> You haven't enabled rename detection in git? Or git isn't detecting the
> rename because of the number of changes in the file?

I am not aware of this kind of configuration, internally for git I think it is
the same thing, it is only the way he exposed this to the user that can be changed.
However, it is true that I didn't use the -M flag with format-patch.

I will use it next time, because there also some change in the driver itself, it was
mostly something like s/armada_370_xp/mvebu_v7/


Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 13/16] cpuidle: mvebu: Move the description of the cpuidle states in the platform part
  2014-06-30 13:32     ` Thomas Petazzoni
@ 2014-07-03 13:23       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 13:23 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,

>> In order to prepare the add of new SoCs supports for this cpuidle
> 
> "the add of new SoCs supports for this cpuidle" -> "the addition of the
> support for more SoCs in this cpuidle".
> 
>> driver, this patch moves the description of the state in the platform
>> part. Indeed the number of the cpuidle state, and the value of the
>> flag used will vary depending of the SoC.
> 
> I actually don't really agree with the reasoning here. We can perfectly
> fine have several separate compatible strings, one for each SoC. We do
> this for pinctrl, for clocks, and for many other drivers. Why should it
> be different for the cpuidle driver? I know the function to enter idle
> will most likely implemented in arch/arm/mach-mvebu/ because those
> functions are generally too tightly coupled with a bunch of system
> registers changes, but the description of the different idle states can
> just as well be inside the cpuidle driver itself.

So that would means a different probe and driver name for each SOC?
Indeed it is doable. With my solution adding the support for a new Soc
won't modify the cpu idle driver itself, so the merge would be easier.
But I admit that it is a misuse of the mach- directory.


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 13/16] cpuidle: mvebu: Move the description of the cpuidle states in the platform part
@ 2014-07-03 13:23       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

>> In order to prepare the add of new SoCs supports for this cpuidle
> 
> "the add of new SoCs supports for this cpuidle" -> "the addition of the
> support for more SoCs in this cpuidle".
> 
>> driver, this patch moves the description of the state in the platform
>> part. Indeed the number of the cpuidle state, and the value of the
>> flag used will vary depending of the SoC.
> 
> I actually don't really agree with the reasoning here. We can perfectly
> fine have several separate compatible strings, one for each SoC. We do
> this for pinctrl, for clocks, and for many other drivers. Why should it
> be different for the cpuidle driver? I know the function to enter idle
> will most likely implemented in arch/arm/mach-mvebu/ because those
> functions are generally too tightly coupled with a bunch of system
> registers changes, but the description of the different idle states can
> just as well be inside the cpuidle driver itself.

So that would means a different probe and driver name for each SOC?
Indeed it is doable. With my solution adding the support for a new Soc
won't modify the cpu idle driver itself, so the merge would be easier.
But I admit that it is a misuse of the mach- directory.


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 14/16] ARM: mvebu: Add CPU idle support for Armada 370
  2014-06-30 13:36     ` Thomas Petazzoni
@ 2014-07-03 15:03       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 15:03 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,



>> it have only 2 cpuidle states. Thanks to the previous patches, adding
> 
> have -> has.
> 
>> the support for this new SoCs required only the modification of the
> 
> required -> requires.
> 
>> architecture specific part.
> 
> May not be true if we move the cpuidle states back into the cpuidle
> driver, as I suggested in a comment to one of the previous patch.

Yes indeed :/

> 
>> The message in case of failure to suspend the system was switched from
>> warn to debug. Indeed due to the "slow exit process from the deep idle
>> state" in Armada 370, this situation happens quite often. Using the
>> _debug version avoids spamming the kernel logs, but still allows to
>> enable it if needed.
> 
> Is it really expected that the system fails to enter the idle state? I
> must say I don't really see the relation with the slow exit from deep
> idle state, because the do_armada_xp_370_cpu_suspend() function is only
> here to *enter* the idle state, so how is entering the deep idle state
> related to an issue when exiting the idle state?

The issue is related to the cache management but not to the slow exit
contrary to what I wrote.

We can see in the public datasheet, Figure 105:Deep Idle Simplified
Flows. The last instruction done by software is WFI, but before being
really in deep idle, the HW flush the L2 cache. This procedure is long
and can take a lot of time. Any wakup event interrupt during the L2
flush in the power down procedure the HW can stop the flush and make the
CPU return after the WFI.

I will update the explanation.

[...]

>> -	/*
>> -	 * On Armada 370, there is "a slow exit process from the deep
>> -	 * idle state due to heavy L1/L2 cache cleanup operations
>> -	 * performed by the BootROM software". To avoid this, we
>> -	 * replace the restart code of the bootrom by a a simple jump
>> -	 * to the boot address. Then the code located at this boot
>> -	 * address will take care of the initialization.
>> -	 */
>> -	if (of_machine_is_compatible("marvell,armada370"))
>> -		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
>> -				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
> 
> So we're almost entirely reverting/moving the code added by "[PATCH
> 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370".
> Maybe there is an issue in your series, and the workaround for cpuidle
> support on Armada 370 should only be added in this patch, and not
> earlier?

My idea when I kept "ARM: mvebu: Add workaround for cpuidle support for
Armada 370", was to justify the introduction of the common function for
the boot address work around. But it don't really make sens in the end.


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 14/16] ARM: mvebu: Add CPU idle support for Armada 370
@ 2014-07-03 15:03       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 15:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,



>> it have only 2 cpuidle states. Thanks to the previous patches, adding
> 
> have -> has.
> 
>> the support for this new SoCs required only the modification of the
> 
> required -> requires.
> 
>> architecture specific part.
> 
> May not be true if we move the cpuidle states back into the cpuidle
> driver, as I suggested in a comment to one of the previous patch.

Yes indeed :/

> 
>> The message in case of failure to suspend the system was switched from
>> warn to debug. Indeed due to the "slow exit process from the deep idle
>> state" in Armada 370, this situation happens quite often. Using the
>> _debug version avoids spamming the kernel logs, but still allows to
>> enable it if needed.
> 
> Is it really expected that the system fails to enter the idle state? I
> must say I don't really see the relation with the slow exit from deep
> idle state, because the do_armada_xp_370_cpu_suspend() function is only
> here to *enter* the idle state, so how is entering the deep idle state
> related to an issue when exiting the idle state?

The issue is related to the cache management but not to the slow exit
contrary to what I wrote.

We can see in the public datasheet, Figure 105:Deep Idle Simplified
Flows. The last instruction done by software is WFI, but before being
really in deep idle, the HW flush the L2 cache. This procedure is long
and can take a lot of time. Any wakup event interrupt during the L2
flush in the power down procedure the HW can stop the flush and make the
CPU return after the WFI.

I will update the explanation.

[...]

>> -	/*
>> -	 * On Armada 370, there is "a slow exit process from the deep
>> -	 * idle state due to heavy L1/L2 cache cleanup operations
>> -	 * performed by the BootROM software". To avoid this, we
>> -	 * replace the restart code of the bootrom by a a simple jump
>> -	 * to the boot address. Then the code located at this boot
>> -	 * address will take care of the initialization.
>> -	 */
>> -	if (of_machine_is_compatible("marvell,armada370"))
>> -		mvebu_boot_addr_wa(ARMADA_370_CRYPT0_ENG_ID, pmsu_mp_phys_base +
>> -				PMSU_BOOT_ADDR_REDIRECT_OFFSET(0));
> 
> So we're almost entirely reverting/moving the code added by "[PATCH
> 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370".
> Maybe there is an issue in your series, and the workaround for cpuidle
> support on Armada 370 should only be added in this patch, and not
> earlier?

My idea when I kept "ARM: mvebu: Add workaround for cpuidle support for
Armada 370", was to justify the introduction of the common function for
the boot address work around. But it don't really make sens in the end.


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
  2014-07-01 14:35     ` Thomas Petazzoni
@ 2014-07-03 15:09       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 15:09 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,

> On Fri, 27 Jun 2014 15:22:56 +0200, Gregory CLEMENT wrote:
> 
>> +ENTRY(armada_38x_cpu_resume)
>> +	/* do we need it for Armada 38x*/
>> +ARM_BE8(setend	be )			@ go BE8 if entered LE
> 
> We logically needed this, but I've confirmed, and indeed it is really
> needed for cpuidle to work properly on Armada 38x in big-endian
> configuration.
> 

OK
Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
@ 2014-07-03 15:09       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,

> On Fri, 27 Jun 2014 15:22:56 +0200, Gregory CLEMENT wrote:
> 
>> +ENTRY(armada_38x_cpu_resume)
>> +	/* do we need it for Armada 38x*/
>> +ARM_BE8(setend	be )			@ go BE8 if entered LE
> 
> We logically needed this, but I've confirmed, and indeed it is really
> needed for cpuidle to work properly on Armada 38x in big-endian
> configuration.
> 

OK
Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* Re: [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
  2014-06-30 15:07     ` Thomas Petazzoni
@ 2014-07-03 15:29       ` Gregory CLEMENT
  -1 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 15:29 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Daniel Lezcano, Rafael J. Wysocki, linux-pm, Jason Cooper,
	Andrew Lunn, Sebastian Hesselbarth, Lior Amsalem, Tawfik Bayouk,
	Nadav Haklai, Ezequiel Garcia, linux-arm-kernel

Hi Thomas,


>> Unlike the Armada XP and the Armada 370, this SoC uses a Cortex A9
>> core.
> 
> Isn't there some more details missing in this sentence? When I read it,
> at the end of the sentence, I'm wondering "and so what? what does this
> implies in terms of cpuidle support?".

Humm, actually, it the next sentence was wrongly formulate. Using a
Cortex A9 implies(or at least encourage) the use of ARM L2 cache and of
the SCU.

> 
>> Beside this, the main difference for the cpu idle is the way to
>> handle the L2 cache and the use of SCU.


[...]

>>  		pr_err("unable to request region\n");
>>  		ret = -EBUSY;
>> +
> 
> This change.
> 
>>  		goto out;
>>  	}
>>  
>> @@ -163,7 +181,6 @@ static int __init mvebu_v7_pmsu_init(void)
>>  		ret = -ENOMEM;
>>  		goto out;
>>  	}
>> -
> 
> And this one look like spurious changes not related to the patch.

yes of course.

> 
>>   out:
>>  	of_node_put(np);
>>  	return ret;
>> @@ -260,6 +277,27 @@ static int armada_xp_370_cpu_suspend(unsigned long deepidle)
>>  	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
>>  }
>>  
>> +static noinline int do_armada_38x_cpu_suspend(unsigned long deepidle)
>> +{
>> +	mvebu_v7_pmsu_idle_prepare(deepidle, false);
>> +	/*
>> +	 * Already flushed cache, but do it again as the outer cache
>> +	 * functions dirty the cache with spinlocks
>> +	 */
>> +	v7_exit_coherency_flush(louis);
>> +
>> +	scu_power_mode(scu_base, SCU_PM_POWEROFF);
>> +
>> +	cpu_do_idle();
> 
> I see cpu_do_idle() does dsb() and wfi(), so why don't we use in the
> do_armada_370_xp_cpu_suspend() function ?

We can use cpu_do_idle() in do_armada_370_xp_cpu_suspend() too.

> 
>> +
>> +	return 1;
> 
> You return 1 here, but in the do_armada_370_xp_cpu_suspend() function
> you return zero. Is the return value being used? Why use 0 in one case
> and 1 in the other?

return 1 means error. But I think it was a nasty trick to not enter in the
CPU_PM_EXIT case. I forgot to go back on this, once the cpu idle was working
on Armada 38x. I will take care of it in the next series.

[...]

>> +{
>> +	struct device_node *np;
>> +	void __iomem *mpsoc_base;
>> +	u32 reg;
>> +
>> +	np = of_find_compatible_node(NULL, NULL,
>> +				"marvell,armada-380-coherency-fabric");
>> +	if (!np)
>> +		return false;
> 
> 		return -ENODEV;
> 
>> +	of_node_put(np);
>> +
>> +	np = of_find_compatible_node(NULL, NULL,
>> +				"marvell,armada-380-mpcore-soc-ctrl");
>> +	if (!np)
>> +		return false;
> 
> 		return -ENODEV;
> 
>> +	mpsoc_base = of_iomap(np, 0);
>> +	WARN_ON(!mpsoc_base);
> 
> WARN_ON() seems a bit weak for something that will make the next line
> crash the kernel. What about:
> 
> 	if (!mpsoc_base)
> 		return -ENOMEM;
> 
> I think the of_node_put(np) should be here.

OK


Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

* [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x
@ 2014-07-03 15:29       ` Gregory CLEMENT
  0 siblings, 0 replies; 120+ messages in thread
From: Gregory CLEMENT @ 2014-07-03 15:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Thomas,


>> Unlike the Armada XP and the Armada 370, this SoC uses a Cortex A9
>> core.
> 
> Isn't there some more details missing in this sentence? When I read it,
> at the end of the sentence, I'm wondering "and so what? what does this
> implies in terms of cpuidle support?".

Humm, actually, it the next sentence was wrongly formulate. Using a
Cortex A9 implies(or at least encourage) the use of ARM L2 cache and of
the SCU.

> 
>> Beside this, the main difference for the cpu idle is the way to
>> handle the L2 cache and the use of SCU.


[...]

>>  		pr_err("unable to request region\n");
>>  		ret = -EBUSY;
>> +
> 
> This change.
> 
>>  		goto out;
>>  	}
>>  
>> @@ -163,7 +181,6 @@ static int __init mvebu_v7_pmsu_init(void)
>>  		ret = -ENOMEM;
>>  		goto out;
>>  	}
>> -
> 
> And this one look like spurious changes not related to the patch.

yes of course.

> 
>>   out:
>>  	of_node_put(np);
>>  	return ret;
>> @@ -260,6 +277,27 @@ static int armada_xp_370_cpu_suspend(unsigned long deepidle)
>>  	return cpu_suspend(deepidle, do_armada_xp_370_cpu_suspend);
>>  }
>>  
>> +static noinline int do_armada_38x_cpu_suspend(unsigned long deepidle)
>> +{
>> +	mvebu_v7_pmsu_idle_prepare(deepidle, false);
>> +	/*
>> +	 * Already flushed cache, but do it again as the outer cache
>> +	 * functions dirty the cache with spinlocks
>> +	 */
>> +	v7_exit_coherency_flush(louis);
>> +
>> +	scu_power_mode(scu_base, SCU_PM_POWEROFF);
>> +
>> +	cpu_do_idle();
> 
> I see cpu_do_idle() does dsb() and wfi(), so why don't we use in the
> do_armada_370_xp_cpu_suspend() function ?

We can use cpu_do_idle() in do_armada_370_xp_cpu_suspend() too.

> 
>> +
>> +	return 1;
> 
> You return 1 here, but in the do_armada_370_xp_cpu_suspend() function
> you return zero. Is the return value being used? Why use 0 in one case
> and 1 in the other?

return 1 means error. But I think it was a nasty trick to not enter in the
CPU_PM_EXIT case. I forgot to go back on this, once the cpu idle was working
on Armada 38x. I will take care of it in the next series.

[...]

>> +{
>> +	struct device_node *np;
>> +	void __iomem *mpsoc_base;
>> +	u32 reg;
>> +
>> +	np = of_find_compatible_node(NULL, NULL,
>> +				"marvell,armada-380-coherency-fabric");
>> +	if (!np)
>> +		return false;
> 
> 		return -ENODEV;
> 
>> +	of_node_put(np);
>> +
>> +	np = of_find_compatible_node(NULL, NULL,
>> +				"marvell,armada-380-mpcore-soc-ctrl");
>> +	if (!np)
>> +		return false;
> 
> 		return -ENODEV;
> 
>> +	mpsoc_base = of_iomap(np, 0);
>> +	WARN_ON(!mpsoc_base);
> 
> WARN_ON() seems a bit weak for something that will make the next line
> crash the kernel. What about:
> 
> 	if (!mpsoc_base)
> 		return -ENOMEM;
> 
> I think the of_node_put(np) should be here.

OK


Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

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

end of thread, other threads:[~2014-07-03 15:30 UTC | newest]

Thread overview: 120+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-27 13:22 [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x Gregory CLEMENT
2014-06-27 13:22 ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 01/16] ARM: mvebu: Sort the headers of pmsu.c in alphabetic order Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 12:16   ` Thomas Petazzoni
2014-06-30 12:16     ` Thomas Petazzoni
2014-07-02 22:57     ` Gregory CLEMENT
2014-07-02 22:57       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 02/16] ARM: mvebu: Add a common function for the boot address work around Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 12:40   ` Thomas Petazzoni
2014-06-30 12:40     ` Thomas Petazzoni
2014-07-02 22:58     ` Gregory CLEMENT
2014-07-02 22:58       ` Gregory CLEMENT
2014-07-03  7:16       ` Thomas Petazzoni
2014-07-03  7:16         ` Thomas Petazzoni
2014-07-01 14:34   ` Thomas Petazzoni
2014-07-01 14:34     ` Thomas Petazzoni
2014-07-02 22:58     ` Gregory CLEMENT
2014-07-02 22:58       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 03/16] ARM: mvebu: Add function to export the physical address of the boot register Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-27 14:14   ` Gregory CLEMENT
2014-06-27 14:14     ` Gregory CLEMENT
2014-06-30 12:46   ` Thomas Petazzoni
2014-06-30 12:46     ` Thomas Petazzoni
2014-07-03  8:39     ` Gregory CLEMENT
2014-07-03  8:39       ` Gregory CLEMENT
2014-07-03  9:25       ` Thomas Petazzoni
2014-07-03  9:25         ` Thomas Petazzoni
2014-07-03 10:07         ` Gregory CLEMENT
2014-07-03 10:07           ` Gregory CLEMENT
2014-07-01 11:46   ` Thomas Petazzoni
2014-07-01 11:46     ` Thomas Petazzoni
2014-07-01 15:02     ` Ezequiel Garcia
2014-07-01 15:02       ` Ezequiel Garcia
2014-06-27 13:22 ` [PATCH 04/16] ARM: mvebu: Use the common function for Armada 375 SMP workaround Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 05/16] ARM: mvebu: Add workaround for cpuidle support for Armada 370 Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 12:50   ` Thomas Petazzoni
2014-06-30 12:50     ` Thomas Petazzoni
2014-07-03  8:44     ` Gregory CLEMENT
2014-07-03  8:44       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 06/16] ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 12:57   ` Thomas Petazzoni
2014-06-30 12:57     ` Thomas Petazzoni
2014-07-03  8:47     ` Gregory CLEMENT
2014-07-03  8:47       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 07/16] ARM: mvebu: Make the CPU idle initialization more generic Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-27 14:15   ` Gregory CLEMENT
2014-06-27 14:15     ` Gregory CLEMENT
2014-06-28 14:56     ` Jason Cooper
2014-06-28 14:56       ` Jason Cooper
2014-06-30 10:30       ` Gregory CLEMENT
2014-06-30 10:30         ` Gregory CLEMENT
2014-06-30 14:07   ` Thomas Petazzoni
2014-06-30 14:07     ` Thomas Petazzoni
2014-07-03  8:54     ` Gregory CLEMENT
2014-07-03  8:54       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 08/16] ARM: mvebu: Use a local variable to store the resume address Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 15:09   ` Thomas Petazzoni
2014-06-30 15:09     ` Thomas Petazzoni
2014-07-03  9:24     ` Gregory CLEMENT
2014-07-03  9:24       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 09/16] ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 15:43   ` Thomas Petazzoni
2014-06-30 15:43     ` Thomas Petazzoni
2014-07-03 12:50     ` Gregory CLEMENT
2014-07-03 12:50       ` Gregory CLEMENT
2014-07-03 12:55       ` Thomas Petazzoni
2014-07-03 12:55         ` Thomas Petazzoni
2014-06-27 13:22 ` [PATCH 10/16] ARM: mvebu: Export the SCU address Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 11/16] ARM: mvebu: dts: Add CA9 MPcore SoC Controller node Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 15:37   ` Thomas Petazzoni
2014-06-30 15:37     ` Thomas Petazzoni
2014-07-03 12:51     ` Gregory CLEMENT
2014-07-03 12:51       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 12/16] cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7 Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 13:28   ` Thomas Petazzoni
2014-06-30 13:28     ` Thomas Petazzoni
2014-07-03 13:08     ` Gregory CLEMENT
2014-07-03 13:08       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 13/16] cpuidle: mvebu: Move the description of the cpuidle states in the platform part Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 13:32   ` Thomas Petazzoni
2014-06-30 13:32     ` Thomas Petazzoni
2014-07-03 13:23     ` Gregory CLEMENT
2014-07-03 13:23       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 14/16] ARM: mvebu: Add CPU idle support for Armada 370 Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 13:36   ` Thomas Petazzoni
2014-06-30 13:36     ` Thomas Petazzoni
2014-07-03 15:03     ` Gregory CLEMENT
2014-07-03 15:03       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 15/16] ARM: mvebu: Add CPU idle support for Armada 38x Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 15:07   ` Thomas Petazzoni
2014-06-30 15:07     ` Thomas Petazzoni
2014-07-03 15:29     ` Gregory CLEMENT
2014-07-03 15:29       ` Gregory CLEMENT
2014-07-01 14:35   ` Thomas Petazzoni
2014-07-01 14:35     ` Thomas Petazzoni
2014-07-03 15:09     ` Gregory CLEMENT
2014-07-03 15:09       ` Gregory CLEMENT
2014-06-27 13:22 ` [PATCH 16/16] ARM: mvebu: defconfig: Enable CPU Idle support in mvebu_v7_defconfig Gregory CLEMENT
2014-06-27 13:22   ` Gregory CLEMENT
2014-06-30 15:45 ` [PATCH 00/16] CPU Idle for Armada 370 and Armada 38x Thomas Petazzoni
2014-06-30 15:45   ` Thomas Petazzoni
2014-06-30 15:51   ` Gregory CLEMENT
2014-06-30 15:51     ` Gregory CLEMENT
2014-07-01 14:38     ` Thomas Petazzoni
2014-07-01 14:38       ` Thomas Petazzoni

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.