summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2009-10-24 18:33:01 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2009-10-24 18:33:01 +0000
commit4a8797cf0cc40ac45ac79a01d293c2c7a4f16f14 (patch)
tree2386bb9e0042fb4f99e910779b0cecb75011ee63 /sys/powerpc
parentce2ebccca84ef8b4473c3f31b6474e515ef200c2 (diff)
downloadFreeBSD-src-4a8797cf0cc40ac45ac79a01d293c2c7a4f16f14.zip
FreeBSD-src-4a8797cf0cc40ac45ac79a01d293c2c7a4f16f14.tar.gz
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.
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/include/hid.h7
-rw-r--r--sys/powerpc/powerpc/cpu.c242
2 files changed, 160 insertions, 89 deletions
diff --git a/sys/powerpc/include/hid.h b/sys/powerpc/include/hid.h
index 3ba5b55..94f9965 100644
--- a/sys/powerpc/include/hid.h
+++ b/sys/powerpc/include/hid.h
@@ -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
*
diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c
index 9f245e2..1325207 100644
--- a/sys/powerpc/powerpc/cpu.c
+++ b/sys/powerpc/powerpc/cpu.c
@@ -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 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;
-
- 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;
+ case MPC8240:
+ case MPC8245:
+ cpu_6xx_setup(cpuid, vers);
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);
+}
+
OpenPOWER on IntegriCloud