diff mbox

[2/3] ARM: smp_scu: enable SCU standby support

Message ID 1405928755-19413-3-git-send-email-shawn.guo@freescale.com (mailing list archive)
State New, archived
Headers show

Commit Message

Shawn Guo July 21, 2014, 7:45 a.m. UTC
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 <shawn.guo@freescale.com>
---
 arch/arm/kernel/smp_scu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Will Deacon July 21, 2014, 8:51 a.m. UTC | #1
On Mon, Jul 21, 2014 at 08:45:54AM +0100, Shawn Guo wrote:
> 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 <shawn.guo@freescale.com>
> ---
>  arch/arm/kernel/smp_scu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
> index c947508f84e6..9f29d167d02c 100644
> --- a/arch/arm/kernel/smp_scu.c
> +++ b/arch/arm/kernel/smp_scu.c
> @@ -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;

I don't think this bit exists on all revisions of the A9.

Will
Shawn Guo July 21, 2014, 9:27 a.m. UTC | #2
On Mon, Jul 21, 2014 at 09:51:50AM +0100, Will Deacon wrote:
> On Mon, Jul 21, 2014 at 08:45:54AM +0100, Shawn Guo wrote:
> > 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 <shawn.guo@freescale.com>
> > ---
> >  arch/arm/kernel/smp_scu.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
> > index c947508f84e6..9f29d167d02c 100644
> > --- a/arch/arm/kernel/smp_scu.c
> > +++ b/arch/arm/kernel/smp_scu.c
> > @@ -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;
> 
> 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
Will Deacon July 21, 2014, 9:44 a.m. UTC | #3
On Mon, Jul 21, 2014 at 10:27:04AM +0100, Shawn Guo wrote:
> On Mon, Jul 21, 2014 at 09:51:50AM +0100, Will Deacon wrote:
> > On Mon, Jul 21, 2014 at 08:45:54AM +0100, Shawn Guo wrote:
> > > 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 <shawn.guo@freescale.com>
> > > ---
> > >  arch/arm/kernel/smp_scu.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
> > > index c947508f84e6..9f29d167d02c 100644
> > > --- a/arch/arm/kernel/smp_scu.c
> > > +++ b/arch/arm/kernel/smp_scu.c
> > > @@ -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;
> > 
> > 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
Catalin Marinas July 21, 2014, 10:26 a.m. UTC | #4
On Mon, Jul 21, 2014 at 05:27:04PM +0800, Shawn Guo wrote:
> On Mon, Jul 21, 2014 at 09:51:50AM +0100, Will Deacon wrote:
> > On Mon, Jul 21, 2014 at 08:45:54AM +0100, Shawn Guo wrote:
> > > 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 <shawn.guo@freescale.com>
> > > ---
> > >  arch/arm/kernel/smp_scu.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
> > > index c947508f84e6..9f29d167d02c 100644
> > > --- a/arch/arm/kernel/smp_scu.c
> > > +++ b/arch/arm/kernel/smp_scu.c
> > > @@ -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;
> > 
> > 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.
Shawn Guo July 22, 2014, 1:56 a.m. UTC | #5
On Mon, Jul 21, 2014 at 10:44:52AM +0100, Will Deacon wrote:
> > > > @@ -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.
> > 
> > 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
Shawn Guo July 22, 2014, 2:09 a.m. UTC | #6
On Mon, Jul 21, 2014 at 11:26:38AM +0100, Catalin Marinas wrote:
> 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?

> 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
Catalin Marinas July 22, 2014, 4:13 p.m. UTC | #7
On Tue, Jul 22, 2014 at 03:09:12AM +0100, Shawn Guo wrote:
> On Mon, Jul 21, 2014 at 11:26:38AM +0100, Catalin Marinas wrote:
> > 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).

> > 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.
Shawn Guo July 23, 2014, 4:50 a.m. UTC | #8
On Tue, Jul 22, 2014 at 05:13:31PM +0100, Catalin Marinas wrote:
> 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
Catalin Marinas July 23, 2014, 4:45 p.m. UTC | #9
On Wed, Jul 23, 2014 at 05:50:57AM +0100, Shawn Guo wrote:
> On Tue, Jul 22, 2014 at 05:13:31PM +0100, Catalin Marinas wrote:
> > 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.
Shawn Guo July 24, 2014, 8:49 a.m. UTC | #10
On Wed, Jul 23, 2014 at 05:45:21PM +0100, Catalin Marinas wrote:
> On Wed, Jul 23, 2014 at 05:50:57AM +0100, Shawn Guo wrote:
> > On Tue, Jul 22, 2014 at 05:13:31PM +0100, Catalin Marinas wrote:
> > > 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.

Thanks for checking, Catalin.

Shawn
diff mbox

Patch

diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index c947508f84e6..9f29d167d02c 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -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);
 
 	/*