Enable SCU standby support at core level
Subsystems (3)
cover Enable SCU standby support at core level
With SCU standby support, SCU CLK will be turned off when all processors are in WFI mode. And the clock will be turned on when any processor leaves WFI mode. This behavior should be preferable in terms of power efficiency of system idle.
The patch series enables SCU standby support in SCU core function scu_enable(), and then clean up the SCU standby enabling code at i.MX platform level.
Shawn Guo (3):
ARM: smp_scu: use macro for SCU enable bit
ARM: smp_scu: enable SCU standby support
ARM: imx: remove SCU standby enable code
arch/arm/kernel/smp_scu.c | 6 ++++-- arch/arm/mach-imx/common.h | 2 -- arch/arm/mach-imx/cpuidle-imx6q.c | 4 ---- arch/arm/mach-imx/platsmp.c | 10 ---------- 4 files changed, 4 insertions(+), 18 deletions(-)
Signature · 1 line
1.9.1
PATCH 1/3 ARM: smp_scu: use macro for SCU enable bit
Use macro instead of magic number for SCU enable bit.
--- arch/arm/kernel/smp_scu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm/kernel/smp_scu.c +3 -2
@@ -17,6 +17,7 @@#include <asm/cputype.h> #define SCU_CTRL 0x00 +#define SCU_ENABLE (1 << 0)#define SCU_CONFIG 0x04#define SCU_CPU_STATUS 0x08#define SCU_INVALIDATE 0x0c
@@ -50,10 +51,10 @@ void scu_enable(void __iomem *scu_base) scu_ctrl =readl_relaxed (scu_base +SCU_CTRL );/* already enabled? */ -if (scu_ctrl &1 ) +if (scu_ctrl &SCU_ENABLE )return ; - scu_ctrl |=1 ; + scu_ctrl |=SCU_ENABLE ;writel_relaxed (scu_ctrl, scu_base +SCU_CTRL );/*
Signature · 1 line
1.9.1
PATCH 2/3 ARM: smp_scu: enable SCU standby support
In reply to Shawn GuoWith SCU standby enabled, SCU CLK will be turned off when all processors are in WFI mode. And the clock will be turned on when any processor leaves WFI mode.
This behavior should be preferable in terms of power efficiency of system idle. So let's set the SCU standby bit to enable the support in function scu_enable().
--- arch/arm/kernel/smp_scu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/kernel/smp_scu.c +2 -1
@@ -18,6 +18,7 @@#define SCU_CTRL 0x00#define SCU_ENABLE (1 << 0) +#define SCU_STANDBY_ENABLE (1 << 5)#define SCU_CONFIG 0x04#define SCU_CPU_STATUS 0x08#define SCU_INVALIDATE 0x0c
@@ -54,7 +55,7 @@ void scu_enable(void __iomem *scu_base)if (scu_ctrl &SCU_ENABLE )return ; - scu_ctrl |=SCU_ENABLE ; + scu_ctrl |=SCU_ENABLE |SCU_STANDBY_ENABLE ;writel_relaxed (scu_ctrl, scu_base +SCU_CTRL );/*
Signature · 1 line
1.9.1
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 26 lines · Shawn Guo
With SCU standby enabled, SCU CLK will be turned off when all processors are in WFI mode. And the clock will be turned on when any processor leaves WFI mode.
This behavior should be preferable in terms of power efficiency of system idle. So let's set the SCU standby bit to enable the support in function
scu_enable().Signed-off-by Shawn Guo <[email protected]>--- arch/arm/kernel/smp_scu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)arch/arm/kernel/smp_scu.c +1
-0@@ -18,6 +18,7 @@#define SCU_CTRL 0x00#define SCU_ENABLE (1 << 0) +#define SCU_STANDBY_ENABLE (1 << 5)#define SCU_CONFIG 0x04#define SCU_CPU_STATUS 0x08#define SCU_INVALIDATE 0x0c
arch/arm/kernel/smp_scu.c void scu_enable(void __iomem *scu_base) · line 58
Quoted 5 lines
arch/arm/kernel/smp_scu.c +1
-1@@ -54,7 +55,7 @@ void scu_enable(void __iomem *scu_base)if (scu_ctrl &SCU_ENABLE )return ; - scu_ctrl |=SCU_ENABLE ; + scu_ctrl |=SCU_ENABLE |SCU_STANDBY_ENABLE ;
I don't think this bit exists on all revisions of the A9.
Will
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 30 lines · Will Deacon
Quoted 29 lines · Shawn Guo
With SCU standby enabled, SCU CLK will be turned off when all processors are in WFI mode. And the clock will be turned on when any processor leaves WFI mode.
This behavior should be preferable in terms of power efficiency of system idle. So let's set the SCU standby bit to enable the support in function
scu_enable().Signed-off-by Shawn Guo <[email protected]>--- arch/arm/kernel/smp_scu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)arch/arm/kernel/smp_scu.c +1
-0@@ -18,6 +18,7 @@#define SCU_CTRL 0x00#define SCU_ENABLE (1 << 0) +#define SCU_STANDBY_ENABLE (1 << 5)#define SCU_CONFIG 0x04#define SCU_CPU_STATUS 0x08#define SCU_INVALIDATE 0x0c@@ -54,7 +55,7 @@ void scu_enable(void __iomem *scu_base)if (scu_ctrl &SCU_ENABLE )return ;
Quoted 4 lines
arch/arm/kernel/smp_scu.c void scu_enable(void __iomem *scu_base) · line 58
Quoted 2 lines
arch/arm/kernel/smp_scu.c +1
-1- scu_ctrl |=SCU_ENABLE ; + scu_ctrl |=SCU_ENABLE |SCU_STANDBY_ENABLE ;I don't think this bit exists on all revisions of the A9.
Thanks for the info, Will. Is there any side-effect to write the standby bit on those revisions which do not define the bit?
Shawn
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 31 lines · Shawn Guo
Quoted 30 lines · Will Deacon
Quoted 29 lines · Shawn Guo
With SCU standby enabled, SCU CLK will be turned off when all processors are in WFI mode. And the clock will be turned on when any processor leaves WFI mode.
This behavior should be preferable in terms of power efficiency of system idle. So let's set the SCU standby bit to enable the support in function
scu_enable().Signed-off-by Shawn Guo <[email protected]>--- arch/arm/kernel/smp_scu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)arch/arm/kernel/smp_scu.c +1
-0@@ -18,6 +18,7 @@#define SCU_CTRL 0x00#define SCU_ENABLE (1 << 0) +#define SCU_STANDBY_ENABLE (1 << 5)#define SCU_CONFIG 0x04#define SCU_CPU_STATUS 0x08#define SCU_INVALIDATE 0x0c@@ -54,7 +55,7 @@ void scu_enable(void __iomem *scu_base)if (scu_ctrl &SCU_ENABLE )return ;
Quoted 7 lines
Quoted 4 lines
arch/arm/kernel/smp_scu.c void scu_enable(void __iomem *scu_base) · line 58
Quoted 2 lines
arch/arm/kernel/smp_scu.c +1
-1- scu_ctrl |=SCU_ENABLE ; + scu_ctrl |=SCU_ENABLE |SCU_STANDBY_ENABLE ;I don't think this bit exists on all revisions of the A9.
Thanks for the info, Will. Is there any side-effect to write the standby bit on those revisions which do not define the bit?
I'm not actually sure what happens at the hardware level, but the TRM is pretty clear in its definition of `RESERVED':
`All reserved bits not used by the implementation must be written as 0 and
read as 0.'
Will
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 9 lines · Will Deacon
Quoted 9 lines
Quoted 8 lines
arch/arm/kernel/smp_scu.c void scu_enable(void __iomem *scu_base) · line 58
Quoted 6 lines
arch/arm/kernel/smp_scu.c +1
-1@@ -54,7 +55,7 @@ void scu_enable(void __iomem *scu_base)if (scu_ctrl &SCU_ENABLE )return ; - scu_ctrl |=SCU_ENABLE ; + scu_ctrl |=SCU_ENABLE |SCU_STANDBY_ENABLE ;I don't think this bit exists on all revisions of the A9.
Quoted 8 lines
Quoted 2 lines
Thanks for the info, Will. Is there any side-effect to write the standby bit on those revisions which do not define the bit?
I'm not actually sure what happens at the hardware level, but the TRM is pretty clear in its definition of `RESERVED':
`All reserved bits not used by the implementation must be written as 0 and
read as 0.'
Okay. Can you please tell which revisions of A9 do not implement this standby bit, so that I can check and skip them? The oldest revision I can find on http://infocenter.arm.com/ is r2p0, which already implements the bit.
Shawn
PATCH 2/3 ARM: smp_scu: enable SCU standby support
In reply to Shawn GuoQuoted 31 lines · Shawn Guo
Quoted 30 lines · Will Deacon
Quoted 29 lines · Shawn Guo
With SCU standby enabled, SCU CLK will be turned off when all processors are in WFI mode. And the clock will be turned on when any processor leaves WFI mode.
This behavior should be preferable in terms of power efficiency of system idle. So let's set the SCU standby bit to enable the support in function
scu_enable().Signed-off-by Shawn Guo <[email protected]>--- arch/arm/kernel/smp_scu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)arch/arm/kernel/smp_scu.c +1
-0@@ -18,6 +18,7 @@#define SCU_CTRL 0x00#define SCU_ENABLE (1 << 0) +#define SCU_STANDBY_ENABLE (1 << 5)#define SCU_CONFIG 0x04#define SCU_CPU_STATUS 0x08#define SCU_INVALIDATE 0x0c@@ -54,7 +55,7 @@ void scu_enable(void __iomem *scu_base)if (scu_ctrl &SCU_ENABLE )return ;
Quoted 7 lines
Quoted 4 lines
arch/arm/kernel/smp_scu.c void scu_enable(void __iomem *scu_base) · line 58
Quoted 2 lines
arch/arm/kernel/smp_scu.c +1
-1- scu_ctrl |=SCU_ENABLE ; + scu_ctrl |=SCU_ENABLE |SCU_STANDBY_ENABLE ;I don't think this bit exists on all revisions of the A9.
Thanks for the info, Will. Is there any side-effect to write the standby bit on those revisions which do not define the bit?
The usual question - could the firmware enable this bit before Linux starts? We already do a read/modify/write sequence here and are only supposed to write the enable bit as the rest are implementation defined.
Signature · 1 line
Catalin
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 2 lines · Catalin Marinas
The usual question - could the firmware enable this bit before Linux starts?
It could, I guess. Actually, on i.MX we're setting this bit in platform code right now. But I think setting this bit makes sense for most of the platforms, so it can reasonably be done in SCU core function. Isn't it the point of having core/common function after all?
Quoted 2 lines
We already do a read/modify/write sequence here and are only supposed to write the enable bit as the rest are implementation defined.
Isn't standby bit implemented by all A9 SCU except a couple of very early revisions (per Will)?
Shawn
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 8 lines · Shawn Guo
Quoted 2 lines · Catalin Marinas
The usual question - could the firmware enable this bit before Linux starts?
It could, I guess. Actually, on i.MX we're setting this bit in platform code right now. But I think setting this bit makes sense for most of the platforms, so it can reasonably be done in SCU core function. Isn't it the point of having core/common function after all?
Only that it wouldn't be consistent. If a platform (like some OMAPs) boots in non-secure mode, the SCU would be already enabled the firmware and your patch would not have any effect (that's one reason on arm64 I try to get some consistency between various platforms and not rely on the kernel which may or may not be able to enable certain features; but it's late to enforced this on arm32).
Quoted 5 lines
Quoted 2 lines
We already do a read/modify/write sequence here and are only supposed to write the enable bit as the rest are implementation defined.
Isn't standby bit implemented by all A9 SCU except a couple of very early revisions (per Will)?
And we don't know the behaviour of setting this bit on such A9 early revisions. So we can try to (1) find out if there are any in the field,
(2) read the RTL to see if anything happens or (3) add a check in Linux for such revisions. I think (3) should be the case but you need to figure out which revisions these are.
Signature · 1 line
Catalin
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 5 lines · Catalin Marinas
And we don't know the behaviour of setting this bit on such A9 early revisions. So we can try to (1) find out if there are any in the field,
(2) read the RTL to see if anything happens or (3) add a check in Linux for such revisions. I think (3) should be the case but you need to figure out which revisions these are.
Can I ask the favor from you ARM folks on that, since I cannot figure it out from any public information?
Shawn
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 9 lines · Shawn Guo
Quoted 5 lines · Catalin Marinas
And we don't know the behaviour of setting this bit on such A9 early revisions. So we can try to (1) find out if there are any in the field,
(2) read the RTL to see if anything happens or (3) add a check in Linux for such revisions. I think (3) should be the case but you need to figure out which revisions these are.Can I ask the favor from you ARM folks on that, since I cannot figure it out from any public information?
Looking through some of the older A9 TRMs, it seems that this bit was added in r2p0. Whether it works as advertised on the relevant SoCs I can't tell.
Signature · 1 line
Catalin
PATCH 2/3 ARM: smp_scu: enable SCU standby support
Quoted 8 lines · Catalin Marinas
Quoted 7 lines · Shawn Guo
Quoted 5 lines · Catalin Marinas
And we don't know the behaviour of setting this bit on such A9 early revisions. So we can try to (1) find out if there are any in the field,
(2) read the RTL to see if anything happens or (3) add a check in Linux for such revisions. I think (3) should be the case but you need to figure out which revisions these are.
Quoted 6 lines
Quoted 2 lines
Can I ask the favor from you ARM folks on that, since I cannot figure it out from any public information?
Looking through some of the older A9 TRMs, it seems that this bit was added in r2p0. Whether it works as advertised on the relevant SoCs I can't tell.
Thanks for checking, Catalin.
Shawn
PATCH 3/3 ARM: imx: remove SCU standby enable code
In reply to Shawn GuoSince we have scu_enable() enables SCU standby support at SCU core level, the code enabling SCU standby at i.MX platform level can be removed now.
--- arch/arm/mach-imx/common.h | 2 -- arch/arm/mach-imx/cpuidle-imx6q.c | 4 ---- arch/arm/mach-imx/platsmp.c | 10 ---------- 3 files changed, 16 deletions(-)
arch/arm/mach-imx/common.h +0 -2
@@ -98,11 +98,9 @@ void imx_set_cpu_arg(int cpu, u32 arg);void v7_secondary_startup (void );void imx_scu_map_io (void );void imx_smp_prepare (void ); -void imx_scu_standby_enable (void );#else static inline void imx_scu_map_io (void ) {}static inline void imx_smp_prepare (void ) {} -static inline void imx_scu_standby_enable (void ) {}#endif void imx_src_init (void );void imx_gpc_init (void );
arch/arm/mach-imx/cpuidle-imx6q.c +0 -4
@@ -66,10 +66,6 @@ static struct cpuidle_driver imx6q_cpuidle_driver = {int __init imx6q_cpuidle_init (void ) { -/* Need to enable SCU standby for entering WAIT modes */ -if (!cpu_is_imx6sx ()) -imx_scu_standby_enable (); -/* Set INT_MEM_CLK_LPM bit to get a reliable WAIT mode support */ imx6q_set_int_mem_clk_lpm (true);
arch/arm/mach-imx/platsmp.c +0 -10
@@ -20,8 +20,6 @@#include "common.h" #include "hardware.h" -#define SCU_STANDBY_ENABLE (1 << 5) -u32 g_diag_reg;static void __iomem *scu_base;
@@ -45,14 +43,6 @@ void __init imx_scu_map_io(void) scu_base =IMX_IO_ADDRESS (base); } -void imx_scu_standby_enable (void ) -{ -u32 val =readl_relaxed (scu_base); - - val |=SCU_STANDBY_ENABLE ; -writel_relaxed (val, scu_base); -} -static int imx_boot_secondary (unsigned int cpu,struct task_struct *idle) {imx_set_cpu_jump (cpu, v7_secondary_startup);
Signature · 1 line
1.9.1