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.
This commit is contained in:
Justin Hibbits 2016-01-01 02:47:40 +00:00
parent 18e6b1b067
commit 637f34cb64
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=293030
6 changed files with 84 additions and 12 deletions

View file

@ -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_ */

View file

@ -131,6 +131,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.
*/

View file

@ -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);
}

View file

@ -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
}

View file

@ -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.

View file

@ -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);
}
};
/**
@ -210,6 +218,22 @@ METHOD void reset {
platform_t _plat;
};
/**
* @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
*/