pmu.c (228277) | pmu.c (259284) |
---|---|
1/*- 2 * Copyright (c) 2006 Michael Lorenz 3 * Copyright 2008 by Nathan Whitehorn 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 13 unchanged lines hidden (view full) --- 22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006 Michael Lorenz 3 * Copyright 2008 by Nathan Whitehorn 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 13 unchanged lines hidden (view full) --- 22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/powerpc/powermac/pmu.c 228277 2011-12-05 14:13:21Z jhibbits $"); | 30__FBSDID("$FreeBSD: head/sys/powerpc/powermac/pmu.c 259284 2013-12-13 02:37:35Z jhibbits $"); |
31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/module.h> 35#include <sys/bus.h> 36#include <sys/conf.h> 37#include <sys/kernel.h> 38#include <sys/clock.h> | 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/module.h> 35#include <sys/bus.h> 36#include <sys/conf.h> 37#include <sys/kernel.h> 38#include <sys/clock.h> |
39#include <sys/proc.h> |
|
39#include <sys/reboot.h> 40#include <sys/sysctl.h> 41 42#include <dev/ofw/ofw_bus.h> 43#include <dev/ofw/openfirm.h> 44#include <dev/led/led.h> 45 | 40#include <sys/reboot.h> 41#include <sys/sysctl.h> 42 43#include <dev/ofw/ofw_bus.h> 44#include <dev/ofw/openfirm.h> 45#include <dev/led/led.h> 46 |
47#include <machine/_inttypes.h> 48#include <machine/altivec.h> /* For save_vec() */ |
|
46#include <machine/bus.h> | 49#include <machine/bus.h> |
50#include <machine/cpu.h> 51#include <machine/fpu.h> /* For save_fpu() */ 52#include <machine/hid.h> |
|
47#include <machine/intr_machdep.h> 48#include <machine/md_var.h> | 53#include <machine/intr_machdep.h> 54#include <machine/md_var.h> |
55#include <machine/pcb.h> |
|
49#include <machine/pio.h> 50#include <machine/resource.h> | 56#include <machine/pio.h> 57#include <machine/resource.h> |
58#include <machine/setjmp.h> |
|
51 52#include <vm/vm.h> 53#include <vm/pmap.h> 54 55#include <sys/rman.h> 56 57#include <dev/adb/adb.h> 58 59#include "clock_if.h" 60#include "pmuvar.h" 61#include "viareg.h" | 59 60#include <vm/vm.h> 61#include <vm/pmap.h> 62 63#include <sys/rman.h> 64 65#include <dev/adb/adb.h> 66 67#include "clock_if.h" 68#include "pmuvar.h" 69#include "viareg.h" |
70#include "uninorthvar.h" /* For unin_chip_sleep()/unin_chip_wake() */ |
|
62 | 71 |
72#define PMU_DEFAULTS PMU_INT_TICK | PMU_INT_ADB | \ 73 PMU_INT_PCEJECT | PMU_INT_SNDBRT | \ 74 PMU_INT_BATTERY | PMU_INT_ENVIRONMENT 75 |
|
63/* 64 * Bus interface 65 */ 66static int pmu_probe(device_t); 67static int pmu_attach(device_t); 68static int pmu_detach(device_t); 69 70/* --- 17 unchanged lines hidden (view full) --- 88 89static void pmu_shutdown(void *xsc, int howto); 90static void pmu_set_sleepled(void *xsc, int onoff); 91static int pmu_server_mode(SYSCTL_HANDLER_ARGS); 92static int pmu_acline_state(SYSCTL_HANDLER_ARGS); 93static int pmu_query_battery(struct pmu_softc *sc, int batt, 94 struct pmu_battstate *info); 95static int pmu_battquery_sysctl(SYSCTL_HANDLER_ARGS); | 76/* 77 * Bus interface 78 */ 79static int pmu_probe(device_t); 80static int pmu_attach(device_t); 81static int pmu_detach(device_t); 82 83/* --- 17 unchanged lines hidden (view full) --- 101 102static void pmu_shutdown(void *xsc, int howto); 103static void pmu_set_sleepled(void *xsc, int onoff); 104static int pmu_server_mode(SYSCTL_HANDLER_ARGS); 105static int pmu_acline_state(SYSCTL_HANDLER_ARGS); 106static int pmu_query_battery(struct pmu_softc *sc, int batt, 107 struct pmu_battstate *info); 108static int pmu_battquery_sysctl(SYSCTL_HANDLER_ARGS); |
109static void pmu_sleep_int(void); |
|
96 97/* 98 * List of battery-related sysctls we might ask for 99 */ 100 101enum { 102 PMU_BATSYSCTL_PRESENT = 1 << 8, 103 PMU_BATSYSCTL_CHARGING = 2 << 8, --- 6 unchanged lines hidden (view full) --- 110}; 111 112static device_method_t pmu_methods[] = { 113 /* Device interface */ 114 DEVMETHOD(device_probe, pmu_probe), 115 DEVMETHOD(device_attach, pmu_attach), 116 DEVMETHOD(device_detach, pmu_detach), 117 DEVMETHOD(device_shutdown, bus_generic_shutdown), | 110 111/* 112 * List of battery-related sysctls we might ask for 113 */ 114 115enum { 116 PMU_BATSYSCTL_PRESENT = 1 << 8, 117 PMU_BATSYSCTL_CHARGING = 2 << 8, --- 6 unchanged lines hidden (view full) --- 124}; 125 126static device_method_t pmu_methods[] = { 127 /* Device interface */ 128 DEVMETHOD(device_probe, pmu_probe), 129 DEVMETHOD(device_attach, pmu_attach), 130 DEVMETHOD(device_detach, pmu_detach), 131 DEVMETHOD(device_shutdown, bus_generic_shutdown), |
118 DEVMETHOD(device_suspend, bus_generic_suspend), 119 DEVMETHOD(device_resume, bus_generic_resume), | |
120 121 /* ADB bus interface */ 122 DEVMETHOD(adb_hb_send_raw_packet, pmu_adb_send), 123 DEVMETHOD(adb_hb_controller_poll, pmu_poll), 124 DEVMETHOD(adb_hb_set_autopoll_mask, pmu_adb_autopoll), 125 126 /* Clock interface */ 127 DEVMETHOD(clock_gettime, pmu_gettime), --- 60 unchanged lines hidden (view full) --- 188 0x00, 0x00, 0x02, 0x02, -1, -1, -1, -1, 189 0x01, 0x01, -1, -1, -1, -1, -1, -1, 190 0x00, 0x00, -1, -1, 0x01, -1, -1, -1, 191 0x01, 0x00, 0x02, 0x02, -1, 0x01, 0x03, 0x01, 192 0x00, 0x01, 0x00, 0x00, 0x00, -1, -1, -1, 193 0x02, -1, -1, -1, -1, -1, -1, -1, 194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1, -1, 195 0x01, 0x01, 0x01, -1, -1, -1, -1, -1, | 132 133 /* ADB bus interface */ 134 DEVMETHOD(adb_hb_send_raw_packet, pmu_adb_send), 135 DEVMETHOD(adb_hb_controller_poll, pmu_poll), 136 DEVMETHOD(adb_hb_set_autopoll_mask, pmu_adb_autopoll), 137 138 /* Clock interface */ 139 DEVMETHOD(clock_gettime, pmu_gettime), --- 60 unchanged lines hidden (view full) --- 200 0x00, 0x00, 0x02, 0x02, -1, -1, -1, -1, 201 0x01, 0x01, -1, -1, -1, -1, -1, -1, 202 0x00, 0x00, -1, -1, 0x01, -1, -1, -1, 203 0x01, 0x00, 0x02, 0x02, -1, 0x01, 0x03, 0x01, 204 0x00, 0x01, 0x00, 0x00, 0x00, -1, -1, -1, 205 0x02, -1, -1, -1, -1, -1, -1, -1, 206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1, -1, 207 0x01, 0x01, 0x01, -1, -1, -1, -1, -1, |
196 0x00, 0x00, -1, -1, -1, -1, 0x04, 0x04, | 208 0x00, 0x00, -1, -1, -1, 0x05, 0x04, 0x04, |
197 0x04, -1, 0x00, -1, -1, -1, -1, -1, 198 0x00, -1, -1, -1, -1, -1, -1, -1, 199 0x01, 0x02, -1, -1, -1, -1, -1, -1, 200 0x00, 0x00, -1, -1, -1, -1, -1, -1, 201 0x02, 0x02, 0x02, 0x04, -1, 0x00, -1, -1, 202 0x01, 0x01, 0x03, 0x02, -1, -1, -1, -1, 203 -1, -1, -1, -1, -1, -1, -1, -1, 204 -1, -1, -1, -1, -1, -1, -1, -1, --- 19 unchanged lines hidden (view full) --- 224 0x05, 0x15, -1, 0x02, -1, -1, -1, -1, 225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 226 0x02, 0x02, -1, -1, -1, -1, -1, -1, 227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 228 0x02, 0x00, 0x03, 0x03, -1, -1, -1, -1, 229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 230 0x04, 0x04, 0x03, 0x09, -1, -1, -1, -1, 231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 209 0x04, -1, 0x00, -1, -1, -1, -1, -1, 210 0x00, -1, -1, -1, -1, -1, -1, -1, 211 0x01, 0x02, -1, -1, -1, -1, -1, -1, 212 0x00, 0x00, -1, -1, -1, -1, -1, -1, 213 0x02, 0x02, 0x02, 0x04, -1, 0x00, -1, -1, 214 0x01, 0x01, 0x03, 0x02, -1, -1, -1, -1, 215 -1, -1, -1, -1, -1, -1, -1, -1, 216 -1, -1, -1, -1, -1, -1, -1, -1, --- 19 unchanged lines hidden (view full) --- 236 0x05, 0x15, -1, 0x02, -1, -1, -1, -1, 237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 238 0x02, 0x02, -1, -1, -1, -1, -1, -1, 239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 0x02, 0x00, 0x03, 0x03, -1, -1, -1, -1, 241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 242 0x04, 0x04, 0x03, 0x09, -1, -1, -1, -1, 243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
232 -1, -1, -1, -1, -1, -1, 0x01, 0x01, | 244 -1, -1, -1, -1, -1, 0x01, 0x01, 0x01, |
233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 234 0x06, -1, -1, -1, -1, -1, -1, -1, 235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 236 0x02, 0x02, -1, -1, -1, -1, -1, -1, 237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 238 0x02, 0x00, 0x00, 0x00, -1, -1, -1, -1, 239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 -1, -1, -1, -1, -1, -1, -1, -1, --- 111 unchanged lines hidden (view full) --- 352 353 sc->sc_autopoll = 0; 354 sc->sc_batteries = 0; 355 sc->adb_bus = NULL; 356 sc->sc_leddev = NULL; 357 358 /* Init PMU */ 359 | 245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 246 0x06, -1, -1, -1, -1, -1, -1, -1, 247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 248 0x02, 0x02, -1, -1, -1, -1, -1, -1, 249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 250 0x02, 0x00, 0x00, 0x00, -1, -1, -1, -1, 251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 252 -1, -1, -1, -1, -1, -1, -1, -1, --- 111 unchanged lines hidden (view full) --- 364 365 sc->sc_autopoll = 0; 366 sc->sc_batteries = 0; 367 sc->adb_bus = NULL; 368 sc->sc_leddev = NULL; 369 370 /* Init PMU */ 371 |
360 reg = PMU_INT_TICK | PMU_INT_ADB | PMU_INT_PCEJECT | PMU_INT_SNDBRT; 361 reg |= PMU_INT_BATTERY; 362 reg |= PMU_INT_ENVIRONMENT; | 372 pmu_write_reg(sc, vBufB, pmu_read_reg(sc, vBufB) | vPB4); 373 pmu_write_reg(sc, vDirB, (pmu_read_reg(sc, vDirB) | vPB4) & ~vPB3); 374 375 reg = PMU_DEFAULTS; |
363 pmu_send(sc, PMU_SET_IMASK, 1, ®, 16, resp); 364 | 376 pmu_send(sc, PMU_SET_IMASK, 1, ®, 16, resp); 377 |
365 pmu_write_reg(sc, vIER, 0x90); /* make sure VIA interrupts are on */ | 378 pmu_write_reg(sc, vIER, 0x94); /* make sure VIA interrupts are on */ |
366 367 pmu_send(sc, PMU_SYSTEM_READY, 1, cmd, 16, resp); 368 pmu_send(sc, PMU_GET_VERSION, 1, cmd, 16, resp); 369 370 /* Initialize child buses (ADB) */ 371 node = ofw_bus_get_node(dev); 372 373 for (child = OF_child(node); child != 0; child = OF_peer(child)) { --- 639 unchanged lines hidden (view full) --- 1013 1014 mtx_lock(&sc->sc_mutex); 1015 pmu_send(sc, PMU_SET_RTC, sizeof(sec), (uint8_t *)&sec, 0, NULL); 1016 mtx_unlock(&sc->sc_mutex); 1017 1018 return (0); 1019} 1020 | 379 380 pmu_send(sc, PMU_SYSTEM_READY, 1, cmd, 16, resp); 381 pmu_send(sc, PMU_GET_VERSION, 1, cmd, 16, resp); 382 383 /* Initialize child buses (ADB) */ 384 node = ofw_bus_get_node(dev); 385 386 for (child = OF_child(node); child != 0; child = OF_peer(child)) { --- 639 unchanged lines hidden (view full) --- 1026 1027 mtx_lock(&sc->sc_mutex); 1028 pmu_send(sc, PMU_SET_RTC, sizeof(sec), (uint8_t *)&sec, 0, NULL); 1029 mtx_unlock(&sc->sc_mutex); 1030 1031 return (0); 1032} 1033 |
1034static register_t sprgs[4]; 1035static register_t srrs[2]; 1036extern void *ap_pcpu; 1037 1038void pmu_sleep_int(void) 1039{ 1040 static u_quad_t timebase = 0; 1041 jmp_buf resetjb; 1042 struct thread *fputd; 1043 struct thread *vectd; 1044 register_t hid0; 1045 register_t msr; 1046 register_t saved_msr; 1047 1048 ap_pcpu = pcpup; 1049 1050 PCPU_SET(restore, &resetjb); 1051 1052 *(unsigned long *)0x80 = 0x100; 1053 saved_msr = mfmsr(); 1054 fputd = PCPU_GET(fputhread); 1055 vectd = PCPU_GET(vecthread); 1056 if (fputd != NULL) 1057 save_fpu(fputd); 1058 if (vectd != NULL) 1059 save_vec(vectd); 1060 if (setjmp(resetjb) == 0) { 1061 sprgs[0] = mfspr(SPR_SPRG0); 1062 sprgs[1] = mfspr(SPR_SPRG1); 1063 sprgs[2] = mfspr(SPR_SPRG2); 1064 sprgs[3] = mfspr(SPR_SPRG3); 1065 srrs[0] = mfspr(SPR_SRR0); 1066 srrs[1] = mfspr(SPR_SRR1); 1067 timebase = mftb(); 1068 powerpc_sync(); 1069 flush_disable_caches(); 1070 hid0 = mfspr(SPR_HID0); 1071 hid0 = (hid0 & ~(HID0_DOZE | HID0_NAP)) | HID0_SLEEP; 1072 powerpc_sync(); 1073 isync(); 1074 msr = mfmsr() | PSL_POW; 1075 mtspr(SPR_HID0, hid0); 1076 powerpc_sync(); 1077 1078 while (1) 1079 mtmsr(msr); 1080 } 1081 mttb(timebase); 1082 PCPU_SET(curthread, curthread); 1083 PCPU_SET(curpcb, curthread->td_pcb); 1084 pmap_activate(curthread); 1085 powerpc_sync(); 1086 mtspr(SPR_SPRG0, sprgs[0]); 1087 mtspr(SPR_SPRG1, sprgs[1]); 1088 mtspr(SPR_SPRG2, sprgs[2]); 1089 mtspr(SPR_SPRG3, sprgs[3]); 1090 mtspr(SPR_SRR0, srrs[0]); 1091 mtspr(SPR_SRR1, srrs[1]); 1092 mtmsr(saved_msr); 1093 if (fputd == curthread) 1094 enable_fpu(curthread); 1095 if (vectd == curthread) 1096 enable_vec(curthread); 1097 powerpc_sync(); 1098} 1099 1100int 1101pmu_set_speed(int low_speed) 1102{ 1103 struct pmu_softc *sc; 1104 uint8_t sleepcmd[] = {'W', 'O', 'O', 'F', 0}; 1105 uint8_t resp[16]; 1106 1107 sc = device_get_softc(pmu); 1108 pmu_write_reg(sc, vIER, 0x10); 1109 spinlock_enter(); 1110 mtdec(0x7fffffff); 1111 mb(); 1112 mtdec(0x7fffffff); 1113 1114 sleepcmd[4] = low_speed; 1115 pmu_send(sc, PMU_CPU_SPEED, 5, sleepcmd, 16, resp); 1116 unin_chip_sleep(NULL, 1); 1117 pmu_sleep_int(); 1118 unin_chip_wake(NULL); 1119 1120 mtdec(1); /* Force a decrementer exception */ 1121 spinlock_exit(); 1122 pmu_write_reg(sc, vIER, 0x90); 1123 1124 return (0); 1125} |
|