summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/mpc85xx
diff options
context:
space:
mode:
authorjhibbits <jhibbits@FreeBSD.org>2016-01-01 02:47:40 +0000
committerjhibbits <jhibbits@FreeBSD.org>2016-01-01 02:47:40 +0000
commite13a7f7a36d05e1e0c6d72b3d0c4cd76bf28ffb1 (patch)
treeb6d22b953c5f3ecd118777f5ad688cc08248ddef /sys/powerpc/mpc85xx
parentb8e70bf7efef670381034d0f5a8ded060def0121 (diff)
downloadFreeBSD-src-e13a7f7a36d05e1e0c6d72b3d0c4cd76bf28ffb1.zip
FreeBSD-src-e13a7f7a36d05e1e0c6d72b3d0c4cd76bf28ffb1.tar.gz
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.
Diffstat (limited to 'sys/powerpc/mpc85xx')
-rw-r--r--sys/powerpc/mpc85xx/mpc85xx.h6
-rw-r--r--sys/powerpc/mpc85xx/platform_mpc85xx.c37
2 files changed, 43 insertions, 0 deletions
diff --git a/sys/powerpc/mpc85xx/mpc85xx.h b/sys/powerpc/mpc85xx/mpc85xx.h
index ac8b8ff..e806225 100644
--- a/sys/powerpc/mpc85xx/mpc85xx.h
+++ b/sys/powerpc/mpc85xx/mpc85xx.h
@@ -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);
diff --git a/sys/powerpc/mpc85xx/platform_mpc85xx.c b/sys/powerpc/mpc85xx/platform_mpc85xx.c
index c84561d..3a36e6d 100644
--- a/sys/powerpc/mpc85xx/platform_mpc85xx.c
+++ b/sys/powerpc/mpc85xx/platform_mpc85xx.c
@@ -80,6 +80,8 @@ static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref);
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);
+}
OpenPOWER on IntegriCloud