On 7/7/2011 8:50 AM, Lorenzo Pieralisi wrote:
When a CLUSTER is powered down the SCU must be reinitialized on
warm-boot.
This patch adds a hook to reset the SCU, which implies invalidating
TAG RAMs and renabling it.

The scu virtual address is saved in a static variable when the SCU
is first enabled at boot; this allows common idle code to be
generic and avoid relying on platform code to get the address at
run-time.
On warm-boot the SCU TAG RAM is invalidated and the SCU enabled if
it is not already enabled.

The reset can be skipped altogether thanks to save/restore
framework flags.

Flushing D$ cache is cumbersome since the system just comes out of
reset, which invalidates caches in the process if needed (A9), that
is why the scu_enable function is not reused as it is to reset the SCU.

If the init function is extended, there might not be a need for
a SCU specific hook, since the init function can be reused to
reinitialize the SCU at boot provided it is removed from the init
section and kept in memory.

Signed-off-by: Lorenzo Pieralisi<lorenzo.pieral...@arm.com>
---
  arch/arm/include/asm/smp_scu.h |    3 ++-
  arch/arm/kernel/smp_scu.c      |   33 ++++++++++++++++++++++++++++++---
  2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
index 4eb6d00..cfaa68e 100644
--- a/arch/arm/include/asm/smp_scu.h
+++ b/arch/arm/include/asm/smp_scu.h
@@ -8,7 +8,8 @@
  #ifndef __ASSEMBLER__
  unsigned int scu_get_core_count(void __iomem *);
  void scu_enable(void __iomem *);
-int scu_power_mode(void __iomem *, unsigned int);
+int scu_power_mode(unsigned int);
+void scu_reset(void);
  #endif

  #endif
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index a1e757c..980ced9 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -20,6 +20,7 @@
  #define SCU_INVALIDATE                0x0c
  #define SCU_FPGA_REVISION     0x10

+static void __iomem *scu_va;

Change log and patch doesn't seems to match. I remember suggesting
this change to Russell when "scu_power_mode()" was introduced.
His preference was to have scu_base passed as part of the API.
  /*
   * Get the number of CPU cores from the SCU configuration
   */
@@ -36,6 +37,7 @@ void __init scu_enable(void __iomem *scu_base)
  {
        u32 scu_ctrl;

+       scu_va = scu_base;
        scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
        /* already enabled? */
        if (scu_ctrl&  1)
@@ -59,7 +61,7 @@ void __init scu_enable(void __iomem *scu_base)
   * has the side effect of disabling coherency, caches must have been
   * flushed.  Interrupts must also have been disabled.
   */
-int scu_power_mode(void __iomem *scu_base, unsigned int mode)
+int scu_power_mode(unsigned int mode)
  {
        unsigned int val;
        int cpu = smp_processor_id();
@@ -67,9 +69,34 @@ int scu_power_mode(void __iomem *scu_base, unsigned int mode)
        if (mode>  3 || mode == 1 || cpu>  3)
                return -EINVAL;

-       val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu)&  ~0x03;
+       val = __raw_readb(scu_va + SCU_CPU_STATUS + cpu)&  ~0x03;
        val |= mode;
-       __raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu);
+       __raw_writeb(val, scu_va + SCU_CPU_STATUS + cpu);

        return 0;
  }
+
+/*
+ * Reinitialise the SCU after power-down
+ */
+
+void scu_reset(void)
+{
+       u32 scu_ctrl;
+
+       scu_ctrl = __raw_readl(scu_va + SCU_CTRL);
+       /* already enabled? */
+       if (scu_ctrl&  1)
+               return;
+       /*
+        * SCU TAGS should be invalidated on boot-up
+        */
+       __raw_writel(0xffff, scu_va + SCU_INVALIDATE);
+       /*
+        *  Coming out of reset, dcache invalidated
+        *  no need to go through the whole hog again
+        *  just enable the SCU and pop out
+        */
+       scu_ctrl |= 1;
+       __raw_writel(scu_ctrl, scu_va + SCU_CTRL);
+}


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to