Author: jhibbits
Date: Fri Jan  1 02:47:40 2016
New Revision: 293030
URL: https://svnweb.freebsd.org/changeset/base/293030

Log:
  Extend idle support for newer Book-E cores.
  
  Newer Book-E cores (e500mc, e5500, e6500) do not support the WE bit in the 
MSR,
  and instead delegate CPU idling to the SoC.
  
  Perhaps in the future the QORIQ_DPAA option for the mpc85xx platform will 
become
  a subclass, which will eliminate most of the #ifdef's.

Modified:
  head/sys/powerpc/include/platform.h
  head/sys/powerpc/mpc85xx/mpc85xx.h
  head/sys/powerpc/mpc85xx/platform_mpc85xx.c
  head/sys/powerpc/powerpc/cpu.c
  head/sys/powerpc/powerpc/platform.c
  head/sys/powerpc/powerpc/platform_if.m

Modified: head/sys/powerpc/include/platform.h
==============================================================================
--- head/sys/powerpc/include/platform.h Fri Jan  1 02:25:10 2016        
(r293029)
+++ head/sys/powerpc/include/platform.h Fri Jan  1 02:47:40 2016        
(r293030)
@@ -57,6 +57,8 @@ void  platform_smp_ap_init(void);
 const char *installed_platform(void);
 void platform_probe_and_attach(void);
 
+void   platform_cpu_idle(int);
+
 void platform_sleep(void);
   
 #endif /* _MACHINE_PLATFORM_H_ */

Modified: head/sys/powerpc/mpc85xx/mpc85xx.h
==============================================================================
--- head/sys/powerpc/mpc85xx/mpc85xx.h  Fri Jan  1 02:25:10 2016        
(r293029)
+++ head/sys/powerpc/mpc85xx/mpc85xx.h  Fri Jan  1 02:47:40 2016        
(r293030)
@@ -132,6 +132,12 @@ extern vm_offset_t         ccsrbar_va;
 #define        OCP85XX_RSTCR           (CCSRBAR_VA + 0xe00b0)
 
 /*
+ * Run Control/Power Management Registers.
+ */
+#define        OCP85XX_RCPM_CDOZSR     (CCSRBAR_VA + 0xe2004)
+#define        OCP85XX_RCPM_CDOZCR     (CCSRBAR_VA + 0xe200c)
+
+/*
  * Prototypes.
  */
 uint32_t ccsr_read4(uintptr_t addr);

Modified: head/sys/powerpc/mpc85xx/platform_mpc85xx.c
==============================================================================
--- head/sys/powerpc/mpc85xx/platform_mpc85xx.c Fri Jan  1 02:25:10 2016        
(r293029)
+++ head/sys/powerpc/mpc85xx/platform_mpc85xx.c Fri Jan  1 02:47:40 2016        
(r293030)
@@ -80,6 +80,8 @@ static int mpc85xx_smp_first_cpu(platfor
 static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref);
 static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref);
 static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu);
+static void mpc85xx_idle(platform_t, int cpu);
+static int mpc85xx_idle_wakeup(platform_t plat, int cpu);
 
 static void mpc85xx_reset(platform_t);
 
@@ -95,6 +97,8 @@ static platform_method_t mpc85xx_methods
        PLATFORMMETHOD(platform_smp_start_cpu,  mpc85xx_smp_start_cpu),
 
        PLATFORMMETHOD(platform_reset,          mpc85xx_reset),
+       PLATFORMMETHOD(platform_idle,           mpc85xx_idle),
+       PLATFORMMETHOD(platform_idle_wakeup,    mpc85xx_idle_wakeup),
 
        PLATFORMMETHOD_END
 };
@@ -478,3 +482,36 @@ mpc85xx_reset(platform_t plat)
                ;
 }
 
+static void
+mpc85xx_idle(platform_t plat, int cpu)
+{
+#ifdef QORIQ_DPAA
+       uint32_t reg;
+
+       reg = ccsr_read4(OCP85XX_RCPM_CDOZCR);
+       ccsr_write4(OCP85XX_RCPM_CDOZCR, reg | (1 << cpu));
+       ccsr_read4(OCP85XX_RCPM_CDOZCR);
+#else
+       register_t msr;
+
+       msr = mfmsr();
+       /* Freescale E500 core RM section 6.4.1. */
+       __asm __volatile("msync; mtmsr %0; isync" ::
+           "r" (msr | PSL_WE));
+#endif
+}
+
+static int
+mpc85xx_idle_wakeup(platform_t plat, int cpu)
+{
+#ifdef QORIQ_DPAA
+       uint32_t reg;
+
+       reg = ccsr_read4(OCP85XX_RCPM_CDOZCR);
+       ccsr_write4(OCP85XX_RCPM_CDOZCR, reg & ~(1 << cpu));
+       ccsr_read4(OCP85XX_RCPM_CDOZCR);
+
+       return (1);
+#endif
+       return (0);
+}

Modified: head/sys/powerpc/powerpc/cpu.c
==============================================================================
--- head/sys/powerpc/powerpc/cpu.c      Fri Jan  1 02:25:10 2016        
(r293029)
+++ head/sys/powerpc/powerpc/cpu.c      Fri Jan  1 02:47:40 2016        
(r293030)
@@ -607,12 +607,6 @@ cpu_idle(int busy)
            busy, curcpu);
 }
 
-int
-cpu_idle_wakeup(int cpu)
-{
-       return (0);
-}
-
 static void
 cpu_idle_60x(sbintime_t sbt)
 {
@@ -651,14 +645,9 @@ cpu_idle_60x(sbintime_t sbt)
 static void
 cpu_idle_booke(sbintime_t sbt)
 {
-       register_t msr;
-
-       msr = mfmsr();
 
 #ifdef E500
-       /* Freescale E500 core RM section 6.4.1. */
-       __asm __volatile("msync; mtmsr %0; isync" ::
-           "r" (msr | PSL_WE));
+       platform_cpu_idle(PCPU_GET(cpuid));
 #endif
 }
 

Modified: head/sys/powerpc/powerpc/platform.c
==============================================================================
--- head/sys/powerpc/powerpc/platform.c Fri Jan  1 02:25:10 2016        
(r293029)
+++ head/sys/powerpc/powerpc/platform.c Fri Jan  1 02:47:40 2016        
(r293030)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/ktr.h>
 #include <sys/mutex.h>
+#include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/smp.h>
 #include <sys/sysctl.h>
@@ -252,6 +253,19 @@ cpu_reset()
         PLATFORM_RESET(plat_obj);
 }
 
+int
+cpu_idle_wakeup(int cpu)
+{
+       return (PLATFORM_IDLE_WAKEUP(plat_obj, cpu));
+}
+
+void
+platform_cpu_idle(int cpu)
+{
+
+       PLATFORM_IDLE(plat_obj, cpu);
+}
+
 /*
  * Platform install routines. Highest priority wins, using the same
  * algorithm as bus attachment.

Modified: head/sys/powerpc/powerpc/platform_if.m
==============================================================================
--- head/sys/powerpc/powerpc/platform_if.m      Fri Jan  1 02:25:10 2016        
(r293029)
+++ head/sys/powerpc/powerpc/platform_if.m      Fri Jan  1 02:47:40 2016        
(r293030)
@@ -84,6 +84,14 @@ CODE {
        {
                return;
        }
+       static void platform_null_idle(platform_t plat, int cpu)
+       {
+               return;
+       }
+       static int platform_null_idle_wakeup(platform_t plat, int cpu)
+       {
+               return (0);
+       }
 };
 
 /**
@@ -211,6 +219,22 @@ METHOD void reset {
 };
 
 /**
+ * @brief Idle a CPU
+ */
+METHOD void idle {
+       platform_t      _plat;
+       int             _cpu;
+} DEFAULT platform_null_idle;
+
+/**
+ * @brief Wake up an idle CPU
+ */
+METHOD int idle_wakeup {
+       platform_t      _plat;
+       int             _cpu;
+} DEFAULT platform_null_idle_wakeup;
+
+/**
  * @brief Suspend the CPU
  */
 METHOD void sleep {
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to