CPU Idle for Armada 370 and Armada 38x
Subsystems (5)
cover CPU Idle for Armada 370 and Armada 38x
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
Signature · 1 line
1.8.1.2
PATCH 1/16 ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
Sorting the headers in alphabetic order will help to reduce the conflict when adding new headers later.
--- arch/arm/mach-mvebu/pmsu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/mach-mvebu/pmsu.c +3 -3
@@ -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>
Signature · 1 line
1.8.1.2
PATCH 1/16 ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
Gregory,
Quoted 13 lines · Gregory CLEMENT
Sorting the headers in alphabetic order will help to reduce the conflict when adding new headers later.
Signed-off-by Gregory CLEMENT <[email protected]>--- arch/arm/mach-mvebu/pmsu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)arch/arm/mach-mvebu/pmsu.c +0
-0
arch/arm/mach-mvebu/pmsu.c line 24
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c +1
-2@@ -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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 1/16 ARM: mvebu: Sort the headers of pmsu.c in alphabetic order
Hi Thomas,
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c line 24
Quoted 6 lines
#include <
linux/cpu_pm.h>arch/arm/mach-mvebu/pmsu.c +1
-2-#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:
Quoted 5 lines
#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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 2/16 ARM: mvebu: Add a common function for the boot address work around
In reply to Gregory CLEMENTOn 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().
--- 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(+)
arch/arm/mach-mvebu/pmsu.c +31 -0
@@ -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;
arch/arm/mach-mvebu/pmsu.h +1 -0
@@ -12,5 +12,6 @@#define __MACH_MVEBU_PMSU_Hint 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 */
arch/arm/mach-mvebu/pmsu_ll.S +19 -0
@@ -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)
Signature · 1 line
1.8.1.2
PATCH 2/16 ARM: mvebu: Add a common function for the boot address work around
Gregory,
Quoted 1 line · Gregory CLEMENT
On some of the mvebu SoC and due to internal bootrom issue, CPU
"due to an internal BootROM issue, the CPU"
Quoted 1 line
initial jump code should be placed in SRAM memory of the SoC. In order
"in SRAM memory" -> "in the SRAM memory".
Quoted 2 lines
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
Quoted 2 lines
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.
Quoted 1 line
This work around currently needed for booting SMP on Aramda 375 Z1 and
This work around *is* currently needed for SMP support on *Armada*.
Quoted 1 line
will be needed for cpuidle support on Armada 370. Instead of duplicate
duplicate -> duplicating.
Quoted 1 line
the same code, this commit introduce a common function to handle it:
introduce -> introduces.
Quoted 1 line
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.
Quoted 6 lines
Signed-off-by Gregory CLEMENT <[email protected]>--- 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?
Quoted 14 lines
arch/arm/mach-mvebu/pmsu.c +1
-0@@ -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>
arch/arm/mach-mvebu/pmsu.c static void __iomem *pmsu_mp_base; · line 67
Quoted 4 lines
arch/arm/mach-mvebu/pmsu.c +1
-0@@ -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.
arch/arm/mach-mvebu/pmsu.c static void __iomem *pmsu_mp_base; · line 68
Quoted 1 line
arch/arm/mach-mvebu/pmsu.c +1
-0+#define CRYPT0_ENG_ATTR 0x1
For consistency, I'd prefer to see this being passed as argument to mvebu_boot_addr_wa().
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c +5
-0+#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 );
arch/arm/mach-mvebu/pmsu.c void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr) · line 100
Quoted 7 lines
arch/arm/mach-mvebu/pmsu.c +4
-0@@ -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.
arch/arm/mach-mvebu/pmsu.c void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr) · line 108
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c +8
-0+{ +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?
arch/arm/mach-mvebu/pmsu.c void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr) · line 110
Quoted 2 lines
arch/arm/mach-mvebu/pmsu.c +2
-0+ +
One too many new line.
arch/arm/mach-mvebu/pmsu.c void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr) · line 116
Quoted 6 lines
arch/arm/mach-mvebu/pmsu.c +6
-0+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);
Quoted 21 lines
arch/arm/mach-mvebu/pmsu.c +2
-0+} +static int __init armada_370_xp_pmsu_init (void ) {struct device_node *np;arch/arm/mach-mvebu/pmsu.h +1
-0@@ -12,5 +12,6 @@#define __MACH_MVEBU_PMSU_Hint 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 */ arch/arm/mach-mvebu/pmsu_ll.S +0
-0
arch/arm/mach-mvebu/pmsu_ll.S ARM_BE8(setend be ) @ go BE8 if entered LE · line 32
Quoted 10 lines
arch/arm/mach-mvebu/pmsu_ll.S +7
-0@@ -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.
arch/arm/mach-mvebu/pmsu_ll.S ARM_BE8(setend be ) @ go BE8 if entered LE · line 38
Quoted 6 lines
arch/arm/mach-mvebu/pmsu_ll.S +6
-0+ 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.
arch/arm/mach-mvebu/pmsu_ll.S ARM_BE8(setend be ) @ go BE8 if entered LE · line 44
Quoted 6 lines
arch/arm/mach-mvebu/pmsu_ll.S +6
-0+ * 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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 2/16 ARM: mvebu: Add a common function for the boot address work around
Hi Thomas,
Quoted 5 lines
Quoted 2 lines
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
Quoted 5 lines
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
Quoted 28 lines
Quoted 6 lines
Signed-off-by Gregory CLEMENT <[email protected]>--- 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.candpmsu_ll.Sreally the right files to store this code?Quoted 17 lines
arch/arm/mach-mvebu/pmsu.c +1
-0@@ -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)
Quoted 4 lines
arch/arm/mach-mvebu/pmsu.c static void __iomem *pmsu_mp_base; · line 67
Quoted 1 line
arch/arm/mach-mvebu/pmsu.c +1
-0+#define ARMADA_370_CRYPT0_ENG_ID 0x9Not needed in this file, the MBus window target ID is passed as argument to the
mvebu_boot_addr_wa()function.
OK
Quoted 5 lines
arch/arm/mach-mvebu/pmsu.c static void __iomem *pmsu_mp_base; · line 68
Quoted 2 lines
arch/arm/mach-mvebu/pmsu.c +1
-0+#define CRYPT0_ENG_ATTR 0x1For 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.
Quoted 13 lines
Quoted 13 lines
arch/arm/mach-mvebu/pmsu.c +5
-0+#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)); }
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr) · line 100
Quoted 4 lines
arch/arm/mach-mvebu/pmsu.c +4
-0+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 intcrypto_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.
Quoted 11 lines
arch/arm/mach-mvebu/pmsu.c void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr) · line 108
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c +8
-0+{ +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
Quoted 15 lines
arch/arm/mach-mvebu/pmsu.c void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr) · line 110
Quoted 3 lines
arch/arm/mach-mvebu/pmsu.c +2
-0+ +One too many new line.
arch/arm/mach-mvebu/pmsu.c void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr) · line 116
Quoted 6 lines
arch/arm/mach-mvebu/pmsu.c +6
-0+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:
Quoted 1 line
writel(resume_addr_reg, sram_virt_base + code_len - 4);
Oh yes I forgot it was "iomaped"
Thanks,
Gregory
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 2/16 ARM: mvebu: Add a common function for the boot address work around
Gregory,
Quoted 7 lines · Gregory CLEMENT
Quoted 4 lines
Quoted 1 line
+#define
CRYPT0_ENG_ATTR0x1For 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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 2/16 ARM: mvebu: Add a common function for the boot address work around
In reply to Gregory CLEMENTDear Gregory CLEMENT,
Quoted 10 lines · Gregory CLEMENT
(quoted diff) +10
-0+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,
Review
Quoted 10 lines
(quoted diff) +10
-0+ 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:
arch/arm/mach-mvebu/pmsu.c +4 -2
@@ -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 ); }
Quoted 9 lines
+.global
mvebu_boot_wa_start
+.globalmvebu_boot_wa_end(quoted diff) +7
-0+ +/* 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]
Review
Quoted 10 lines
(quoted diff) +10
-0+ 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:
arch/arm/mach-mvebu/pmsu_ll.S +7 -4
@@ -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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 2/16 ARM: mvebu: Add a common function for the boot address work around
Hi Thomas,
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ /* + * 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 notwritel()here, to keep the native endianness of the system when writing the value:
Ok
[...]
Quoted 25 lines
arch/arm/mach-mvebu/pmsu_ll.S +7
-4@@ -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 valueNote 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 thewritel()call inmvebu_pmsu_set_cpu_boot_addr().
Quoted 1 line
Could you include this in your next iteration of the patches?
Yes sure, and thanks again for having tested it in BE
Gregory
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 3/16 ARM: mvebu: Add function to export the physical address of the boot register
In reply to Gregory CLEMENTIn 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(+)
arch/arm/mach-mvebu/common.h +1 -0
@@ -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);
arch/arm/mach-mvebu/system-controller.c +11 -0
@@ -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); }
Signature · 1 line
1.8.1.2
PATCH 3/16 ARM: mvebu: Add function to export the physical address of the boot register
Quoted 11 lines · Gregory CLEMENT
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
Quoted 55 lines
--- arch/arm/mach-mvebu/common.h | 1 + arch/arm/mach-mvebu/system-controller.c | 11 +++++++++++ 2 files changed, 12 insertions(+)arch/arm/mach-mvebu/common.h +1
-0@@ -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);arch/arm/mach-mvebu/system-controller.c +11
-0@@ -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); }
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 3/16 ARM: mvebu: Add function to export the physical address of the boot register
In reply to Gregory CLEMENTGregory,
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 ?
Quoted 4 lines · Gregory CLEMENT
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."
Quoted 1 line
In the previous version of this workaround the physical address were
were -> was.
Quoted 38 lines
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(+)arch/arm/mach-mvebu/common.h +1
-0@@ -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);arch/arm/mach-mvebu/system-controller.c +1
-0@@ -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;
arch/arm/mach-mvebu/system-controller.c void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr) · line 114
Quoted 5 lines
arch/arm/mach-mvebu/system-controller.c +2
-0@@ -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.
arch/arm/mach-mvebu/system-controller.c void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr) · line 118
Quoted 4 lines
arch/arm/mach-mvebu/system-controller.c +4
-0+{ +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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 3/16 ARM: mvebu: Add function to export the physical address of the boot register
Hi Thomas,
Quoted 8 lines · Thomas Petazzoni
Gregory,
I'm not sure that the best approach to solve this problem. Instead, maybe the
system-controller.ccode 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 insystem-controller.c?
So moving the workaround into mvebu_system_controller_set_cpu_boot_addr() should be the thing to do.
Thanks,
Gregory
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 3/16 ARM: mvebu: Add function to export the physical address of the boot register
Dear Gregory CLEMENT,
Quoted 9 lines · Gregory CLEMENT
Quoted 6 lines
I'm not sure that the best approach to solve this problem. Instead, maybe the
system-controller.ccode 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 insystem-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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 3/16 ARM: mvebu: Add function to export the physical address of the boot register
Hi Thomas,
Quoted 11 lines · Thomas Petazzoni
Dear Gregory CLEMENT,
Quoted 7 lines · Gregory CLEMENT
Quoted 6 lines
I'm not sure that the best approach to solve this problem. Instead, maybe the
system-controller.ccode 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 insystem-controller.c?
Quoted 8 lines
Quoted 2 lines
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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 3/16 ARM: mvebu: Add function to export the physical address of the boot register
In reply to Gregory CLEMENTDear Gregory CLEMENT,
arch/arm/mach-mvebu/system-controller.c void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr) · line 116
Quoted 13 lines · Gregory CLEMENT
static void
__iomem*system_controller_base;arch/arm/mach-mvebu/system-controller.c +5
-0+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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 3/16 ARM: mvebu: Add function to export the physical address of the boot register
Quoted 7 lines · Thomas Petazzoni
Dear Gregory CLEMENT,
Quoted 3 lines · Gregory CLEMENT
static void
__iomem*system_controller_base;
+static u32system_controller_phys_base;
Quoted 14 lines
arch/arm/mach-mvebu/system-controller.c void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr) · line 116
Quoted 10 lines
struct
mvebu_system_controller{arch/arm/mach-mvebu/system-controller.c +4
-0u32 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);
Signature · 3 lines
Ezequiel Garc?a, Free Electrons Embedded Linux, Kernel and Android Engineering http://free-electrons.com
PATCH 4/16 ARM: mvebu: Use the common function for Armada 375 SMP workaround
In reply to Gregory CLEMENTUse 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.
--- arch/arm/mach-mvebu/headsmp-a9.S | 11 ----------- arch/arm/mach-mvebu/platsmp-a9.c | 27 +++------------------------ 2 files changed, 3 insertions(+), 35 deletions(-)
arch/arm/mach-mvebu/headsmp-a9.S +0 -11
@@ -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
arch/arm/mach-mvebu/platsmp-a9.c +3 -24
@@ -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 41extern 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); }
Signature · 1 line
1.8.1.2
PATCH 5/16 ARM: mvebu: Add workaround for cpuidle support for Armada 370
In reply to Gregory CLEMENTOn 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.
--- arch/arm/mach-mvebu/pmsu.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
arch/arm/mach-mvebu/pmsu.c +17 -1
@@ -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);
Signature · 1 line
1.8.1.2
PATCH 5/16 ARM: mvebu: Add workaround for cpuidle support for Armada 370
Dear Gregory CLEMENT,
Quoted 9 lines · Gregory CLEMENT
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>".
arch/arm/mach-mvebu/pmsu.c extern void ll_enable_coherency(void); · line 79
Quoted 7 lines
#define
PMSU_BASE_OFFSET0x100
#definePMSU_REG_SIZE0x1000arch/arm/mach-mvebu/pmsu.c +1
-0@@ -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.
Quoted 23 lines
arch/arm/mach-mvebu/pmsu.c +9
-0+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
arch/arm/mach-mvebu/pmsu.c int __init armada_370_xp_cpu_pm_init(void) · line 333
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +7
-0+* 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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 5/16 ARM: mvebu: Add workaround for cpuidle support for Armada 370
Hi Thomas,
Quoted 10 lines · Thomas Petazzoni
Dear Gregory CLEMENT,
Quoted 7 lines · Gregory CLEMENT
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.
Quoted 8 lines
Quoted 2 lines
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.
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c extern void ll_enable_coherency(void); · line 79
Quoted 8 lines
#define
PMSU_BASE_OFFSET0x100
#definePMSU_REG_SIZE0x1000arch/arm/mach-mvebu/pmsu.c +1
-0@@ -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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 6/16 ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
In reply to Gregory CLEMENTActually 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.
--- arch/arm/mach-mvebu/pmsu.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-)
arch/arm/mach-mvebu/pmsu.c +20 -20
@@ -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);
Signature · 1 line
1.8.1.2
PATCH 6/16 ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
Dear Gregory CLEMENT,
Quoted 8 lines · Gregory CLEMENT
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 <[email protected]>--- 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.
arch/arm/mach-mvebu/pmsu.c static void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void) · line 181
Quoted 3 lines
/* No locking is needed because we only access per-CPU registers */
arch/arm/mach-mvebu/pmsu.c +1
-1-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.
arch/arm/mach-mvebu/pmsu.c void armada_370_xp_pmsu_idle_prepare(bool deepidle) · line 218
Quoted 2 lines
arch/arm/mach-mvebu/pmsu.c +1
-1-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.
arch/arm/mach-mvebu/pmsu.c static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle) · line 251
Quoted 12 lines
{
arch/arm/mach-mvebu/pmsu.c +2
-2-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.
arch/arm/mach-mvebu/pmsu.c static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle) · line 253
Quoted 3 lines
arch/arm/mach-mvebu/pmsu.c +1
-1{ -return cpu_suspend (deepidle, do_armada_370_xp_cpu_suspend); +return cpu_suspend (deepidle, do_armada_xp_370_cpu_suspend);
Ditto.
Thomas
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 6/16 ARM: mvebu: Rename the armada_370_xp into mvebu_v7 in pmsu.c file
Quoted 17 lines · Thomas Petazzoni
Dear Gregory CLEMENT,
Quoted 8 lines · Gregory CLEMENT
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 <[email protected]>--- 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.
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c static void armada_370_xp_pmsu_enable_l2_powerdown_onidle(void) · line 181
Quoted 3 lines
/* No locking is needed because we only access per-CPU registers */
arch/arm/mach-mvebu/pmsu.c +1
-1-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.
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 7/16 ARM: mvebu: Make the CPU idle initialization more generic
In reply to Gregory CLEMENTIn 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.
--- arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-)
arch/arm/mach-mvebu/pmsu.c +31 -8
@@ -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);
Signature · 1 line
1.8.1.2
PATCH 7/16 ARM: mvebu: Make the CPU idle initialization more generic
Quoted 39 lines · Gregory CLEMENT
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 <[email protected]>--- arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-)arch/arm/mach-mvebu/pmsu.c +20
-0@@ -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 */ },
arch/arm/mach-mvebu/pmsu.c static struct notifier_block mvebu_v7_cpu_pm_notifier = { · line 325
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +7
-0+}; +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;
Quoted 30 lines
arch/arm/mach-mvebu/pmsu.c +4
-8/* * 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);
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 7/16 ARM: mvebu: Make the CPU idle initialization more generic
Gregory,
Quoted 53 lines · Gregory CLEMENT
Quoted 39 lines · Gregory CLEMENT
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 <[email protected]>--- arch/arm/mach-mvebu/pmsu.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-)arch/arm/mach-mvebu/pmsu.c +20
-0@@ -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 */ },arch/arm/mach-mvebu/pmsu.c static struct notifier_block mvebu_v7_cpu_pm_notifier = { · line 325
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +7
-0+}; +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)
Review
Quoted 2 lines
(quoted diff) +2
-0+ 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.
PATCH 7/16 ARM: mvebu: Make the CPU idle initialization more generic
Hi Jason,
Quoted 11 lines
Review
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c static struct notifier_block mvebu_v7_cpu_pm_notifier = { · line 325
Quoted 3 lines
arch/arm/mach-mvebu/pmsu.c +3
-0+ 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)
(quoted diff) +2
-0+ 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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 7/16 ARM: mvebu: Make the CPU idle initialization more generic
In reply to Gregory CLEMENTGregory,
Quoted 19 lines · Gregory CLEMENT
arch/arm/mach-mvebu/pmsu.c +19
-0+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, + },
arch/arm/mach-mvebu/pmsu.c static struct notifier_block mvebu_v7_cpu_pm_notifier = { · line 324
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +7
-0+ { /* 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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 7/16 ARM: mvebu: Make the CPU idle initialization more generic
Hi Thomas,
struct device_node *np;
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c static struct notifier_block mvebu_v7_cpu_pm_notifier = { · line 324
Quoted 4 lines
arch/arm/mach-mvebu/pmsu.c +4
-0+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:
Quoted 9 lines
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.
Quoted 4 lines
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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 8/16 ARM: mvebu: Use a local variable to store the resume address
In reply to Gregory CLEMENTThe 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.
--- arch/arm/mach-mvebu/pmsu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/mach-mvebu/pmsu.c +4 -1
@@ -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; }
Signature · 1 line
1.8.1.2
PATCH 8/16 ARM: mvebu: Use a local variable to store the resume address
Dear Gregory CLEMENT,
arch/arm/mach-mvebu/pmsu.c static int mvebu_v7_cpu_pm_notify(struct notifier_block *self, · line 286
Quoted 11 lines · Gregory CLEMENT
arch/arm/mach-mvebu/pmsu.c +3
-1+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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 8/16 ARM: mvebu: Use a local variable to store the resume address
Hi Thomas,
Quoted 14 lines · Thomas Petazzoni
Dear Gregory CLEMENT,
Quoted 10 lines · Gregory CLEMENT
arch/arm/mach-mvebu/pmsu.c +2
-1+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);
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c static int mvebu_v7_cpu_pm_notify(struct notifier_block *self, · line 286
Quoted 1 line
arch/arm/mach-mvebu/pmsu.c +1
-0+mvebu_pmsu_set_cpu_boot_addr (hw_cpu, mvebu_cpu_resume);Instead of doing this in the
CPU_PM_ENTERnotifier, do we have a reason to not do it in thedo_armada_370_xp_cpu_suspend()function, and thendo_armada_38x_suspend()function respectively? Those functions are already SoC-specific, so surely, they already know whether the resume path should go througharmada_370_xp_cpu_resume()orarmada_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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 9/16 ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
In reply to Gregory CLEMENTOn 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.
--- arch/arm/mach-mvebu/pmsu.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
arch/arm/mach-mvebu/pmsu.c +8 -6
@@ -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);
Signature · 1 line
1.8.1.2
PATCH 9/16 ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
Gregory,
arch/arm/mach-mvebu/pmsu.c static void mvebu_v7_pmsu_enable_l2_powerdown_onidle(void) · line 183
Quoted 3 lines · Gregory CLEMENT
/* No locking is needed because we only access per-CPU registers */
arch/arm/mach-mvebu/pmsu.c +1
-1-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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 9/16 ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
Hi Thomas,
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c static void mvebu_v7_pmsu_enable_l2_powerdown_onidle(void) · line 183
Quoted 3 lines
/* No locking is needed because we only access per-CPU registers */
arch/arm/mach-mvebu/pmsu.c +1
-1-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:
Quoted 7 lines
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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 9/16 ARM: mvebu: Make the snoop disable optional in mvebu_v7_pmsu_idle_prepare
Dear Gregory CLEMENT,
Quoted 7 lines · Gregory CLEMENT
Maybe we can use flags, hence we use only one arguments, it became extensible, and more readable too. Something like
#define
PMSU_IDLE_NO_FLAG0
#definePMSU_IDLE_DEEPIDLEBIT(0)
#definePMSU_IDLE_SNOOPDISBIT(1)
Quoted 6 lines
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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 10/16 ARM: mvebu: Export the SCU address
In reply to Gregory CLEMENTThe 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.
--- arch/arm/mach-mvebu/board-v7.c | 9 +++++++-- arch/arm/mach-mvebu/common.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-)
arch/arm/mach-mvebu/board-v7.c +7 -2
@@ -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
arch/arm/mach-mvebu/common.h +2 -0
@@ -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
Signature · 1 line
1.8.1.2
PATCH 11/16 ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
In reply to Gregory CLEMENTThe 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.
--- .../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
Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt new file +14 -0
@@ -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>; +};
arch/arm/boot/dts/armada-38x.dtsi +5 -0
@@ -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>;
Signature · 1 line
1.8.1.2
PATCH 11/16 ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
Gregory,
Quoted 4 lines · Gregory CLEMENT
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.
"""
Quoted 14 lines
Signed-off-by Gregory CLEMENT <[email protected]>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.txtDocumentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt new file +0
-0
Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt line 8
Quoted 8 lines
Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt new file +8
-0@@ -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
Quoted 12 lines
Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt new file +6
-0+ datasheet for the CA9 MPcore SoC Control registers + +mpcore-soc-ctrl at 20d20 { + compatible = "marvell,armada-380-mpcore-soc-ctrl"; + reg = <0x20d20 0x6c>; +};arch/arm/boot/dts/armada-38x.dtsi +0
-0@@ -286,6 +286,11 @@ reg = <0x20800 0x10>;
arch/arm/boot/dts/armada-38x.dtsi line 296
Quoted 10 lines
arch/arm/boot/dts/armada-38x.dtsi +5
-0}; + 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:
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 11/16 ARM: mvebu: dts: Add CA9 MPcore SoC Controller node
Hi Thomas,
Quoted 20 lines · Gregory CLEMENT
Quoted 4 lines
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.
"""
[...]
Quoted 4 lines
Quoted 1 line
+- reg: should be register base and length as documented in the
should be *the* register base and length
reg = <0x21010 0x1c>;
Quoted 4 lines
With those fixed:
Reviewed-by Thomas Petazzoni <[email protected]>
I will apply your change.
Thanks,
Gregory
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 12/16 cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
In reply to Gregory CLEMENTActually 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.
--- 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
arch/arm/mach-mvebu/pmsu.c +1 -1
@@ -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[] = {
drivers/cpuidle/Kconfig.arm +3 -3
@@ -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"
drivers/cpuidle/Makefile +1 -1
@@ -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
drivers/cpuidle/cpuidle-armada-370-xp.c deleted +0 -93
93 lines not on this page · raw message
drivers/cpuidle/cpuidle-mvebu-v7.c new file +93 -0
93 lines not on this page · raw message
Signature · 1 line
1.8.1.2
PATCH 12/16 cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
Gregory,
Quoted 3 lines · Gregory CLEMENT
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.
drivers/cpuidle/Kconfig.arm line 5
Quoted 4 lines
drivers/cpuidle/Kconfig.arm +2
-2-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?
drivers/cpuidle/Kconfig.arm line 8
Quoted 4 lines
drivers/cpuidle/Kconfig.arm +1
-1depends 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.
drivers/cpuidle/cpuidle-armada-370-xp.c
Quoted 5 lines
drivers/cpuidle/cpuidle-armada-370-xp.c deleted +0
-0
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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 12/16 cpuidle: mvebu: Rename the driver from armada-370-xp to mvebu-v7
Hi Thomas,
Quoted 9 lines · Gregory CLEMENT
Quoted 3 lines
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".
Quoted 10 lines
I would also specifically mention the renaming of the driver that requires changing the
pmsu.cfile. It is worth mentioning that this rename, touching bothdrivers/cpuidleandarch/arm/mach-mvebu, may require some special handling in terms of patch merging (the patch mainly touchesdrivers/cpuidleso it should theoretically go through the cpuidle maintainer, but since thepmsu.cfile 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.
Quoted 9 lines
drivers/cpuidle/Kconfig.arm line 5
Quoted 5 lines
drivers/cpuidle/Kconfig.arm +2
-2-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.
Quoted 7 lines
drivers/cpuidle/Kconfig.arm line 8
Quoted 5 lines
drivers/cpuidle/Kconfig.arm +1
-1depends 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
Quoted 9 lines
drivers/cpuidle/cpuidle-armada-370-xp.c
Quoted 6 lines
drivers/cpuidle/cpuidle-armada-370-xp.c deleted +0
-0You 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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 13/16 cpuidle: mvebu: Move the description of the cpuidle states in the platform part
In reply to Gregory CLEMENTIn 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.
--- 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
arch/arm/mach-mvebu/pmsu.c +30 -2
@@ -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; }
drivers/cpuidle/cpuidle-mvebu-v7.c +16 -33
79 lines not on this page · raw message
include/linux/mvebu-v7-cpuidle.h new file +24 -0
@@ -0,0 +1,24 @@ +/* +* Marvell EBU cpuidle defintion +* +* Copyright (C) 2014 Marvell +* +* Gregory CLEMENT <[email protected]> +* +* 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
Signature · 1 line
1.8.1.2
PATCH 13/16 cpuidle: mvebu: Move the description of the cpuidle states in the platform part
Dear Gregory CLEMENT,
Quoted 1 line · Gregory CLEMENT
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".
Quoted 3 lines
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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 13/16 cpuidle: mvebu: Move the description of the cpuidle states in the platform part
Hi Thomas,
Quoted 9 lines
Quoted 1 line
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".
Quoted 3 lines
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.
Quoted 8 lines
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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 14/16 ARM: mvebu: Add CPU idle support for Armada 370
In reply to Gregory CLEMENTUnlike 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.
--- arch/arm/mach-mvebu/pmsu.c | 60 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 13 deletions(-)
arch/arm/mach-mvebu/pmsu.c +47 -13
@@ -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);
Signature · 1 line
1.8.1.2
PATCH 14/16 ARM: mvebu: Add CPU idle support for Armada 370
Dear Gregory CLEMENT,
Quoted 1 line · Gregory CLEMENT
Unlike the Armada XP the Armada 370 always power done the L2 cache, so
power -> powers
done -> down
Quoted 1 line
it have only 2 cpuidle states. Thanks to the previous patches, adding
have -> has.
Quoted 1 line
the support for this new SoCs required only the modification of the
required -> requires.
Quoted 1 line
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.
Quoted 5 lines
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
_debugversion 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?
Quoted 7 lines
arch/arm/mach-mvebu/pmsu.c +7
-0+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 ,
arch/arm/mach-mvebu/pmsu.c static struct notifier_block mvebu_v7_cpu_pm_notifier = { · line 321
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +10
-0+ .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.
Quoted 51 lines
arch/arm/mach-mvebu/pmsu.c +29
-1+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); -/*
arch/arm/mach-mvebu/pmsu.c static int __init mvebu_v7_cpu_pm_init(void) · line 386
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +0
-10-* 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?
arch/arm/mach-mvebu/pmsu.c static int __init mvebu_v7_cpu_pm_init(void) · line 424
Quoted 4 lines
arch/arm/mach-mvebu/pmsu.c +0
-1-mvebu_v7_pmsu_enable_l2_powerdown_onidle ();platform_device_register (&mvebu_v7_cpuidle_device);cpu_pm_register_notifier (&mvebu_v7_cpu_pm_notifier);
Thomas
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 14/16 ARM: mvebu: Add CPU idle support for Armada 370
Hi Thomas,
Quoted 4 lines
Quoted 1 line
it have only 2 cpuidle states. Thanks to the previous patches, adding
have -> has.
Quoted 8 lines
Quoted 1 line
the support for this new SoCs required only the modification of the
required -> requires.
Quoted 1 line
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 :/
Quoted 7 lines
Quoted 6 lines
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
_debugversion avoids spamming the kernel logs, but still allows to enable it if needed.
Quoted 5 lines
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.
[...]
Quoted 9 lines
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c +0
-9-/* -* 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" ))
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c static int __init mvebu_v7_cpu_pm_init(void) · line 386
Quoted 2 lines
arch/arm/mach-mvebu/pmsu.c +0
-2-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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 15/16 ARM: mvebu: Add CPU idle support for Armada 38x
In reply to Gregory CLEMENTUnlike 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.
--- arch/arm/mach-mvebu/pmsu.c | 101 +++++++++++++++++++++++++++++++++++++++++- arch/arm/mach-mvebu/pmsu_ll.S | 14 ++++++ 2 files changed, 113 insertions(+), 2 deletions(-)
arch/arm/mach-mvebu/pmsu.c +99 -2
@@ -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 */ }, };
arch/arm/mach-mvebu/pmsu_ll.S +14 -0
@@ -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
Signature · 1 line
1.8.1.2
PATCH 15/16 ARM: mvebu: Add CPU idle support for Armada 38x
Gregory,
Quoted 2 lines · Gregory CLEMENT
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?".
Quoted 2 lines
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
Quoted 1 line
+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.
arch/arm/mach-mvebu/pmsu.c static int __init mvebu_v7_pmsu_init(void) · line 171
Quoted 6 lines
static struct
platform_devicemvebu_v7_cpuidle_device= {arch/arm/mach-mvebu/pmsu.c +1
-0@@ -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.
arch/arm/mach-mvebu/pmsu.c static int __init mvebu_v7_pmsu_init(void) · line 166
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c +0
-1goto 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.
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c +2
-0out: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) +{
arch/arm/mach-mvebu/pmsu.c static int armada_xp_370_cpu_suspend(unsigned long deepidle) · line 291
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +10
-0+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 ?
Review static int armada_xp_370_cpu_suspend(unsigned long deepidle) · line 293
Quoted 2 lines
(quoted diff) +2
-0+ + 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?
Quoted 11 lines
arch/arm/mach-mvebu/pmsu.c +7
-0+} + +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) {
arch/arm/mach-mvebu/pmsu.c static noinline void mvebu_v7_pmsu_idle_restore(void) · line 271
Quoted 4 lines
arch/arm/mach-mvebu/pmsu.c +0
-1@@ -268,7 +306,6 @@ static noinline void mvebu_v7_pmsu_idle_restore(void)if (pmsu_mp_base ==NULL )return ; -
Spurious change.
Quoted 13 lines
arch/arm/mach-mvebu/pmsu.c +6
-0/* 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 ,
arch/arm/mach-mvebu/pmsu.c static struct mvebu_v7_cpuidle armada_370_cpuidle = { · line 375
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +10
-0+ .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.
arch/arm/mach-mvebu/pmsu.c static __init bool armada_370_cpuidle_init(void) · line 428
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c +1
-0static 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'.
arch/arm/mach-mvebu/pmsu.c static __init bool armada_370_cpuidle_init(void) · line 437
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c +9
-0+{ +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;
arch/arm/mach-mvebu/pmsu.c static __init bool armada_370_cpuidle_init(void) · line 443
Quoted 6 lines
arch/arm/mach-mvebu/pmsu.c +6
-0+of_node_put (np); + + np =of_find_compatible_node (NULL ,NULL , +"marvell,armada-380-mpcore-soc-ctrl" ); +if (!np) +return false;
return -ENODEV;
arch/arm/mach-mvebu/pmsu.c static __init bool armada_370_cpuidle_init(void) · line 445
Quoted 2 lines
arch/arm/mach-mvebu/pmsu.c +2
-0+ 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.
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +10
-0+ +/* 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 */
arch/arm/mach-mvebu/pmsu.c static __init bool armada_370_cpuidle_init(void) · line 465
Quoted 10 lines
arch/arm/mach-mvebu/pmsu.c +10
-0+ 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;
arch/arm/mach-mvebu/pmsu.c static struct of_device_id of_cpuidle_table[] __initdata = { · line 490
Quoted 12 lines
arch/arm/mach-mvebu/pmsu.c +5
-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.
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c +0
-0{ /* end of list */ }, };arch/arm/mach-mvebu/pmsu_ll.S +0
-0
arch/arm/mach-mvebu/pmsu_ll.S ARM_BE8(setend be ) @ go BE8 if entered LE · line 28
Quoted 6 lines
arch/arm/mach-mvebu/pmsu_ll.S +3
-0@@ -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.
Quoted 4 lines
arch/arm/mach-mvebu/pmsu_ll.S +4
-0+ 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
arch/arm/mach-mvebu/pmsu_ll.S ARM_BE8(setend be ) @ go BE8 if entered LE · line 42
Quoted 10 lines
arch/arm/mach-mvebu/pmsu_ll.S +7
-0+ 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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 15/16 ARM: mvebu: Add CPU idle support for Armada 38x
Hi Thomas,
Quoted 6 lines
Quoted 2 lines
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.
Quoted 3 lines
Quoted 3 lines
Beside this, the main difference for the cpu idle is the way to handle the L2 cache and the use of SCU.
[...]
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c static int __init mvebu_v7_pmsu_init(void) · line 171
Quoted 3 lines
arch/arm/mach-mvebu/pmsu.c +1
-0pr_err ("unable to request region\n" ); ret = -EBUSY ; +This change.
Quoted 3 lines
(quoted diff) +0
-0goto out; }
Quoted 7 lines
arch/arm/mach-mvebu/pmsu.c static int __init mvebu_v7_pmsu_init(void) · line 166
Quoted 5 lines
arch/arm/mach-mvebu/pmsu.c +0
-1@@ -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.
Quoted 8 lines
Quoted 8 lines
arch/arm/mach-mvebu/pmsu.c +0
-0out: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); }
Quoted 15 lines
arch/arm/mach-mvebu/pmsu.c static int armada_xp_370_cpu_suspend(unsigned long deepidle) · line 291
Quoted 12 lines
arch/arm/mach-mvebu/pmsu.c +12
-0+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()doesdsb()andwfi(), so why don't we use in thedo_armada_370_xp_cpu_suspend()function ?
We can use cpu_do_idle() in do_armada_370_xp_cpu_suspend() too.
Quoted 7 lines
Review static int armada_xp_370_cpu_suspend(unsigned long deepidle) · line 293
Quoted 3 lines
(quoted diff) +2
-0+ + 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.
[...]
Quoted 27 lines
arch/arm/mach-mvebu/pmsu.c static __init bool armada_370_cpuidle_init(void) · line 437
Quoted 9 lines
arch/arm/mach-mvebu/pmsu.c +9
-0+{ +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;arch/arm/mach-mvebu/pmsu.c static __init bool armada_370_cpuidle_init(void) · line 443
Quoted 6 lines
arch/arm/mach-mvebu/pmsu.c +6
-0+of_node_put (np); + + np =of_find_compatible_node (NULL ,NULL , +"marvell,armada-380-mpcore-soc-ctrl" ); +if (!np) +return false;return -ENODEV;arch/arm/mach-mvebu/pmsu.c static __init bool armada_370_cpuidle_init(void) · line 445
Quoted 2 lines
arch/arm/mach-mvebu/pmsu.c +2
-0+ 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:
Quoted 4 lines
if (!mpsoc_base) return -ENOMEM;I think the
of_node_put(np)should be here.
OK
Thanks,
Gregory
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 15/16 ARM: mvebu: Add CPU idle support for Armada 38x
In reply to Gregory CLEMENTDear Gregory CLEMENT,
arch/arm/mach-mvebu/pmsu_ll.S ARM_BE8(setend be ) @ go BE8 if entered LE · line 28
Quoted 3 lines · Gregory CLEMENT
arch/arm/mach-mvebu/pmsu_ll.S +3
-0+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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 15/16 ARM: mvebu: Add CPU idle support for Armada 38x
Hi Thomas,
Quoted 10 lines · Gregory CLEMENT
arch/arm/mach-mvebu/pmsu_ll.S ARM_BE8(setend be ) @ go BE8 if entered LE · line 28
Quoted 4 lines
arch/arm/mach-mvebu/pmsu_ll.S +3
-0+ENTRY(armada_38x_cpu_resume) + /* do we need it for Armada 38x*/ +ARM_BE8(setend be ) @ go BE8 if entered LEWe 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
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 16/16 ARM: mvebu: defconfig: Enable CPU Idle support in mvebu_v7_defconfig
In reply to Gregory CLEMENTmvebu SoCs such as Armada 370, Armada XP or Armada 38x now support CPU Idle so let's add it in the default configuration.
--- arch/arm/configs/mvebu_v7_defconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/configs/mvebu_v7_defconfig +2 -0
@@ -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
Signature · 1 line
1.8.1.2
cover CPU Idle for Armada 370 and Armada 38x
In reply to Gregory CLEMENTGregory,
Quoted 6 lines · Gregory CLEMENT
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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
cover CPU Idle for Armada 370 and Armada 38x
Quoted 11 lines · Thomas Petazzoni
Gregory,
Quoted 6 lines · Gregory CLEMENT
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.
Quoted 3 lines
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
Quoted 5 lines
Thanks,
Thomas
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
cover CPU Idle for Armada 370 and Armada 38x
Dear Gregory CLEMENT,
Quoted 6 lines · Gregory CLEMENT
Quoted 3 lines
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
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com