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:
parent
b8e70bf7ef
commit
e13a7f7a36
@ -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_ */
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user