diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2009-10-24 18:33:01 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2009-10-24 18:33:01 +0000 |
commit | 4a8797cf0cc40ac45ac79a01d293c2c7a4f16f14 (patch) | |
tree | 2386bb9e0042fb4f99e910779b0cecb75011ee63 /sys | |
parent | ce2ebccca84ef8b4473c3f31b6474e515ef200c2 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/powerpc/include/hid.h | 7 | ||||
-rw-r--r-- | sys/powerpc/powerpc/cpu.c | 242 |
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); +} + |