diff options
author | jhibbits <jhibbits@FreeBSD.org> | 2016-01-01 02:47:40 +0000 |
---|---|---|
committer | jhibbits <jhibbits@FreeBSD.org> | 2016-01-01 02:47:40 +0000 |
commit | e13a7f7a36d05e1e0c6d72b3d0c4cd76bf28ffb1 (patch) | |
tree | b6d22b953c5f3ecd118777f5ad688cc08248ddef /sys/powerpc/mpc85xx | |
parent | b8e70bf7efef670381034d0f5a8ded060def0121 (diff) | |
download | FreeBSD-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.h | 6 | ||||
-rw-r--r-- | sys/powerpc/mpc85xx/platform_mpc85xx.c | 37 |
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); +} |