Turn on NAP mode on G5 systems, and refactor the HID0 setup code a little.

This makes my G5 Xserve sound slightly less like it is filled with
howling banshees.
This commit is contained in:
Nathan Whitehorn 2009-10-24 18:33:01 +00:00
parent 37a7f59644
commit 570d2b25a6
2 changed files with 163 additions and 92 deletions

View File

@ -41,6 +41,7 @@
#define HID0_ECLK 0x02000000 /* CLK_OUT clock type selection */
#define HID0_PAR 0x01000000 /* Disable precharge of ARTRY */
#define HID0_STEN 0x01000000 /* Software table search enable (7450) */
#define HID0_DEEPNAP 0x01000000 /* Enable deep nap mode (970) */
#define HID0_HBATEN 0x00800000 /* High BAT enable (74[45][578]) */
#define HID0_DOZE 0x00800000 /* Enable doze mode */
#define HID0_NAP 0x00400000 /* Enable nap mode */
@ -98,6 +99,12 @@
"\020b16\017TBEN\016SEL_TBCLK\015b19\014b20\013b21\012b22\011b23" \
"\010EN_MAS7_UPDATE\007DCFA\006b26\005b27\004b28\003b29\002b30\001NOPTI"
#define HID0_970_BITMASK \
"\20" \
"\040ONEPPC\037SINGLE\036ISYNCSC\035SERGP\031DEEPNAP\030DOZE" \
"\027NAP\025DPM\023TG\022HANGDETECT\021NHR\020INORDER" \
"\016TBCTRL\015TBEN\012CIABREN\011HDICEEN\001ENATTN"
/*
* HID0 bit definitions per cpu model
*

View File

@ -114,16 +114,19 @@ static char model[64];
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, "");
static void cpu_print_speed(void);
static void cpu_print_cacheinfo(u_int, uint16_t);
static void cpu_6xx_setup(int cpuid, uint16_t vers);
static void cpu_6xx_print_cacheinfo(u_int, uint16_t);
static void cpu_e500_setup(int cpuid, uint16_t vers);
static void cpu_970_setup(int cpuid, uint16_t vers);
void
cpu_setup(u_int cpuid)
{
u_int pvr, maj, min, hid0;
u_int pvr, maj, min;
uint16_t vers, rev, revfmt;
const struct cputab *cp;
const char *name;
char *bitmask;
pvr = mfpvr();
vers = pvr >> 16;
@ -170,10 +173,8 @@ cpu_setup(u_int cpuid)
break;
}
hid0 = mfspr(SPR_HID0);
/*
* Configure power-saving mode.
* Configure CPU
*/
switch (vers) {
case MPC603:
@ -184,102 +185,34 @@ cpu_setup(u_int cpuid)
case IBM750FX:
case MPC7400:
case MPC7410:
case MPC7447A:
case MPC7448:
case MPC7450:
case MPC7455:
case MPC7457:
case MPC8240:
case MPC8245:
/* Select DOZE mode. */
hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
hid0 |= HID0_DOZE | HID0_DPM;
powerpc_pow_enabled = 1;
cpu_6xx_setup(cpuid, vers);
break;
case MPC7448:
case MPC7447A:
case MPC7457:
case MPC7455:
case MPC7450:
/* Enable the 7450 branch caches */
hid0 |= HID0_SGE | HID0_BTIC;
hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
/* Disable BTIC on 7450 Rev 2.0 or earlier and on 7457 */
if (((pvr >> 16) == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
|| (pvr >> 16) == MPC7457)
hid0 &= ~HID0_BTIC;
/* Select NAP mode. */
hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
hid0 |= HID0_NAP | HID0_DPM;
powerpc_pow_enabled = 1;
break;
default:
/* No power-saving mode is available. */ ;
}
switch (vers) {
case IBM750FX:
case MPC750:
hid0 &= ~HID0_DBP; /* XXX correct? */
hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
break;
case MPC7400:
case MPC7410:
hid0 &= ~HID0_SPD;
hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
hid0 |= HID0_EIEC;
break;
case FSL_E500v1:
case FSL_E500v2:
break;
}
mtspr(SPR_HID0, hid0);
switch (vers) {
case MPC7447A:
case MPC7448:
case MPC7450:
case MPC7455:
case MPC7457:
bitmask = HID0_7450_BITMASK;
break;
case FSL_E500v1:
case FSL_E500v2:
bitmask = HID0_E500_BITMASK;
break;
default:
bitmask = HID0_BITMASK;
break;
}
switch (vers) {
case MPC7450:
case MPC7455:
case MPC7457:
case MPC750:
case IBM750FX:
case MPC7400:
case MPC7410:
case MPC7447A:
case MPC7448:
cpu_print_speed();
printf("\n");
if (bootverbose)
cpu_print_cacheinfo(cpuid, vers);
break;
case IBM970:
case IBM970FX:
case IBM970GX:
case IBM970MP:
cpu_print_speed();
printf("\n");
cpu_970_setup(cpuid, vers);
break;
case FSL_E500v1:
case FSL_E500v2:
cpu_e500_setup(cpuid, vers);
break;
default:
printf("\n");
/* HID setup is unknown */
break;
}
printf("cpu%d: HID0 %b\n", cpuid, hid0, bitmask);
printf("\n");
}
void
@ -346,10 +279,101 @@ cpu_est_clockrate(int cpu_id, uint64_t *cps)
}
void
cpu_print_cacheinfo(u_int cpuid, uint16_t vers)
cpu_6xx_setup(int cpuid, uint16_t vers)
{
uint32_t hid;
register_t hid0, pvr;
const char *bitmask;
hid0 = mfspr(SPR_HID0);
pvr = mfpvr();
/*
* Configure power-saving mode.
*/
switch (vers) {
case MPC603:
case MPC603e:
case MPC603ev:
case MPC604ev:
case MPC750:
case IBM750FX:
case MPC7400:
case MPC7410:
case MPC8240:
case MPC8245:
/* Select DOZE mode. */
hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
hid0 |= HID0_DOZE | HID0_DPM;
powerpc_pow_enabled = 1;
break;
case MPC7448:
case MPC7447A:
case MPC7457:
case MPC7455:
case MPC7450:
/* Enable the 7450 branch caches */
hid0 |= HID0_SGE | HID0_BTIC;
hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
/* Disable BTIC on 7450 Rev 2.0 or earlier and on 7457 */
if (((pvr >> 16) == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
|| (pvr >> 16) == MPC7457)
hid0 &= ~HID0_BTIC;
/* Select NAP mode. */
hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
hid0 |= HID0_NAP | HID0_DPM;
powerpc_pow_enabled = 1;
break;
default:
/* No power-saving mode is available. */ ;
}
switch (vers) {
case IBM750FX:
case MPC750:
hid0 &= ~HID0_DBP; /* XXX correct? */
hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
break;
case MPC7400:
case MPC7410:
hid0 &= ~HID0_SPD;
hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
hid0 |= HID0_EIEC;
break;
}
mtspr(SPR_HID0, hid0);
cpu_print_speed();
printf("\n");
if (bootverbose)
cpu_6xx_print_cacheinfo(cpuid, vers);
switch (vers) {
case MPC7447A:
case MPC7448:
case MPC7450:
case MPC7455:
case MPC7457:
bitmask = HID0_7450_BITMASK;
break;
default:
bitmask = HID0_BITMASK;
break;
}
printf("cpu%d: HID0 %b", cpuid, (int)hid0, bitmask);
}
static void
cpu_6xx_print_cacheinfo(u_int cpuid, uint16_t vers)
{
register_t hid;
hid = mfspr(SPR_HID0);
printf("cpu%u: ", cpuid);
@ -395,3 +419,43 @@ cpu_print_cacheinfo(u_int cpuid, uint16_t vers)
} else
printf("L2 cache disabled\n");
}
static void
cpu_e500_setup(int cpuid, uint16_t vers)
{
register_t hid0;
hid0 = mfspr(SPR_HID0);
printf("cpu%d: HID0 %b", cpuid, (int)hid0, HID0_E500_BITMASK);
}
static void
cpu_970_setup(int cpuid, uint16_t vers)
{
uint32_t hid0_hi, hid0_lo;
__asm __volatile ("mfspr %0,%2; clrldi %1,%0,32; srdi %0,%0,32;"
: "=r" (hid0_hi), "=r" (hid0_lo) : "K" (SPR_HID0));
/* Configure power-saving mode */
hid0_hi |= (HID0_NAP | HID0_DPM);
hid0_hi &= ~(HID0_DOZE | HID0_DEEPNAP);
powerpc_pow_enabled = 1;
__asm __volatile (" \
sync; isync; \
sldi %0,%0,32; or %0,%0,%1; \
mtspr %2, %0; \
mfspr %0, %2; mfspr %0, %2; mfspr %0, %2; \
mfspr %0, %2; mfspr %0, %2; mfspr %0, %2; \
sync; isync"
:: "r" (hid0_hi), "r"(hid0_lo), "K" (SPR_HID0));
cpu_print_speed();
printf("\n");
__asm __volatile ("mfspr %0,%1; srdi %0,%0,32;"
: "=r" (hid0_hi) : "K" (SPR_HID0));
printf("cpu%d: HID0 %b", cpuid, (int)(hid0_hi), HID0_970_BITMASK);
}