Skip to contentSkip to conversation

Enable SCU standby support at core level

PATCH Superseded Shawn Guo 3 participants 14 messages Jul 21, 2014 – Jul 24, 2014

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Shawn Guo

author
#0 lore raw

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
author
#1 lore raw

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
index 1aafa0d785eb..c947508f84e6 100644
@@ -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
author
#2 lore raw

PATCH 2/3 ARM: smp_scu: enable SCU standby support

In reply to 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().

---
 arch/arm/kernel/smp_scu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/kernel/smp_scu.c +2 -1
index c947508f84e6..9f29d167d02c 100644
@@ -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
#3 lore raw

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().

---
 arch/arm/kernel/smp_scu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/kernel/smp_scu.c +1 -0
index c947508f84e6..9f29d167d02c 100644
@@ -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

author
#4 lore raw

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().

---
 arch/arm/kernel/smp_scu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/kernel/smp_scu.c +1 -0
index c947508f84e6..9f29d167d02c 100644
@@ -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

#5 lore raw

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().

---
 arch/arm/kernel/smp_scu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/kernel/smp_scu.c +1 -0
index c947508f84e6..9f29d167d02c 100644
@@ -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

author
#6 lore raw

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

#7 lore raw

PATCH 2/3 ARM: smp_scu: enable SCU standby support

In reply to Shawn Guo
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().

---
 arch/arm/kernel/smp_scu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/kernel/smp_scu.c +1 -0
index c947508f84e6..9f29d167d02c 100644
@@ -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
author
#8 lore raw

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

#9 lore raw

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
author
#10 lore raw

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

#11 lore raw

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
author
#12 lore raw

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

author
#13 lore raw

PATCH 3/3 ARM: imx: remove SCU standby enable code

In reply to Shawn Guo

Since 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
index 22ba8973bcb9..1dabf435c592 100644
@@ -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
index 10844d3bb926..aa935787b743 100644
@@ -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
index 5b57c17c06bd..771bd25c1025 100644
@@ -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