Deleted Added
full compact
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, &reg, 16, resp);
364
376 pmu_send(sc, PMU_SET_IMASK, 1, &reg, 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}