diff options
author | Nathan Whitehorn <nwhitehorn@FreeBSD.org> | 2010-03-23 03:14:44 +0000 |
---|---|---|
committer | Nathan Whitehorn <nwhitehorn@FreeBSD.org> | 2010-03-23 03:14:44 +0000 |
commit | 3df9e0375a80324fc2c38fd9a582c31ad286e035 (patch) | |
tree | ed01872a037bb02b93fe09e25506a6a9bb3aa2e3 /sys/powerpc | |
parent | 0e13104de6223fb6ee0c5699d0eea37384b98c11 (diff) | |
download | src-test2-3df9e0375a80324fc2c38fd9a582c31ad286e035.tar.gz src-test2-3df9e0375a80324fc2c38fd9a582c31ad286e035.zip |
Notes
Diffstat (limited to 'sys/powerpc')
-rw-r--r-- | sys/powerpc/aim/nexus.c | 60 | ||||
-rw-r--r-- | sys/powerpc/powermac/cuda.c | 65 | ||||
-rw-r--r-- | sys/powerpc/powermac/cudavar.h | 1 | ||||
-rw-r--r-- | sys/powerpc/powermac/pmu.c | 59 | ||||
-rw-r--r-- | sys/powerpc/powermac/smu.c | 67 |
5 files changed, 190 insertions, 62 deletions
diff --git a/sys/powerpc/aim/nexus.c b/sys/powerpc/aim/nexus.c index d92090b9cf4f..54567b135c6d 100644 --- a/sys/powerpc/aim/nexus.c +++ b/sys/powerpc/aim/nexus.c @@ -60,7 +60,6 @@ #include <sys/systm.h> #include <sys/module.h> #include <sys/bus.h> -#include <sys/clock.h> #include <sys/cons.h> #include <sys/kernel.h> #include <sys/malloc.h> @@ -74,7 +73,6 @@ #include <sys/rman.h> -#include "clock_if.h" #include "ofw_bus_if.h" #include "pic_if.h" @@ -143,12 +141,6 @@ static const char *nexus_ofw_get_type(device_t, device_t); static const char *nexus_ofw_get_compat(device_t, device_t); /* - * Clock interface. - */ -static int nexus_gettime(device_t, struct timespec *); -static int nexus_settime(device_t, struct timespec *); - -/* * Local routines */ static device_t nexus_device_from_node(device_t, phandle_t); @@ -181,10 +173,6 @@ static device_method_t nexus_methods[] = { DEVMETHOD(ofw_bus_get_type, nexus_ofw_get_type), DEVMETHOD(ofw_bus_get_compat, nexus_ofw_get_compat), - /* Clock interface */ - DEVMETHOD(clock_gettime, nexus_gettime), - DEVMETHOD(clock_settime, nexus_settime), - { 0, 0 } }; @@ -240,7 +228,6 @@ nexus_attach(device_t dev) } - clock_register(dev, 1000); return (bus_generic_attach(dev)); } @@ -512,50 +499,3 @@ nexus_ofw_get_compat(device_t bus, device_t dev) return (dinfo->ndi_compatible); } -#define DIFF19041970 2082844800 - -static int -nexus_gettime(device_t dev, struct timespec *ts) -{ - char path[128]; - ihandle_t ih; - phandle_t ph; - u_int rtc; - - ph = OF_finddevice("rtc"); - if (ph == -1) - return (ENOENT); - - OF_package_to_path(ph, path, sizeof(path)); - ih = OF_open(path); - if (ih == -1) - return (ENXIO); - - if (OF_call_method("read-rtc", ih, 0, 1, &rtc)) - return (EIO); - - ts->tv_sec = rtc - DIFF19041970; - ts->tv_nsec = 0; - return (0); -} - -static int -nexus_settime(device_t dev, struct timespec *ts) -{ - char path[128]; - ihandle_t ih; - phandle_t ph; - u_int rtc; - - ph = OF_finddevice("rtc"); - if (ph == -1) - return (ENOENT); - - OF_package_to_path(ph, path, sizeof(path)); - ih = OF_open(path); - if (ih == -1) - return (ENXIO); - - rtc = ts->tv_sec + DIFF19041970; - return ((OF_call_method("write-rtc", ih, 1, 0, rtc) != 0) ? EIO : 0); -} diff --git a/sys/powerpc/powermac/cuda.c b/sys/powerpc/powermac/cuda.c index 203889c56754..230298e35c40 100644 --- a/sys/powerpc/powermac/cuda.c +++ b/sys/powerpc/powermac/cuda.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <sys/conf.h> #include <sys/kernel.h> +#include <sys/clock.h> #include <dev/ofw/ofw_bus.h> #include <dev/ofw/openfirm.h> @@ -55,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include <dev/adb/adb.h> +#include "clock_if.h" #include "cudavar.h" #include "viareg.h" @@ -72,6 +74,12 @@ static u_int cuda_poll(device_t dev); static void cuda_send_inbound(struct cuda_softc *sc); static void cuda_send_outbound(struct cuda_softc *sc); +/* + * Clock interface + */ +static int cuda_gettime(device_t dev, struct timespec *ts); +static int cuda_settime(device_t dev, struct timespec *ts); + static device_method_t cuda_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cuda_probe), @@ -90,6 +98,10 @@ static device_method_t cuda_methods[] = { DEVMETHOD(adb_hb_controller_poll, cuda_poll), DEVMETHOD(adb_hb_set_autopoll_mask, cuda_adb_autopoll), + /* Clock interface */ + DEVMETHOD(clock_gettime, cuda_gettime), + DEVMETHOD(clock_settime, cuda_settime), + { 0, 0 }, }; @@ -173,6 +185,7 @@ cuda_attach(device_t dev) sc->sc_polling = 0; sc->sc_state = CUDA_NOTREADY; sc->sc_autopoll = 0; + sc->sc_rtc = -1; STAILQ_INIT(&sc->sc_inq); STAILQ_INIT(&sc->sc_outq); @@ -236,6 +249,8 @@ cuda_attach(device_t dev) } } + clock_register(dev, 1000); + return (bus_generic_attach(dev)); } @@ -444,8 +459,18 @@ cuda_send_inbound(struct cuda_softc *sc) break; case CUDA_PSEUDO: mtx_lock(&sc->sc_mutex); - if (pkt->data[0] == CMD_AUTOPOLL) + switch (pkt->data[1]) { + case CMD_AUTOPOLL: sc->sc_autopoll = 1; + break; + case CMD_READ_RTC: + memcpy(&sc->sc_rtc, &pkt->data[2], + sizeof(sc->sc_rtc)); + wakeup(&sc->sc_rtc); + break; + case CMD_WRITE_RTC: + break; + } mtx_unlock(&sc->sc_mutex); break; case CUDA_ERROR: @@ -715,3 +740,41 @@ cuda_adb_autopoll(device_t dev, uint16_t mask) { return (0); } +#define DIFF19041970 2082844800 + +static int +cuda_gettime(device_t dev, struct timespec *ts) +{ + struct cuda_softc *sc = device_get_softc(dev); + uint8_t cmd[] = {CUDA_PSEUDO, CMD_READ_RTC}; + + mtx_lock(&sc->sc_mutex); + sc->sc_rtc = -1; + cuda_send(sc, 1, 2, cmd); + if (sc->sc_rtc == -1) + mtx_sleep(&sc->sc_rtc, &sc->sc_mutex, 0, "rtc", 100); + + ts->tv_sec = sc->sc_rtc - DIFF19041970; + ts->tv_nsec = 0; + mtx_unlock(&sc->sc_mutex); + + return (0); +} + +static int +cuda_settime(device_t dev, struct timespec *ts) +{ + struct cuda_softc *sc = device_get_softc(dev); + uint8_t cmd[] = {CUDA_PSEUDO, CMD_WRITE_RTC, 0, 0, 0, 0}; + uint32_t sec; + + sec = ts->tv_sec + DIFF19041970; + memcpy(&cmd[2], &sec, sizeof(sec)); + + mtx_lock(&sc->sc_mutex); + cuda_send(sc, 0, 6, cmd); + mtx_unlock(&sc->sc_mutex); + + return (0); +} + diff --git a/sys/powerpc/powermac/cudavar.h b/sys/powerpc/powermac/cudavar.h index 02791cb08edd..225446494cd3 100644 --- a/sys/powerpc/powermac/cudavar.h +++ b/sys/powerpc/powermac/cudavar.h @@ -90,6 +90,7 @@ struct cuda_softc { int sc_polling; int sc_iic_done; volatile int sc_autopoll; + uint32_t sc_rtc; int sc_i2c_read_len; diff --git a/sys/powerpc/powermac/pmu.c b/sys/powerpc/powermac/pmu.c index 9ddba9e055fa..a980622e0d10 100644 --- a/sys/powerpc/powermac/pmu.c +++ b/sys/powerpc/powermac/pmu.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bus.h> #include <sys/conf.h> #include <sys/kernel.h> +#include <sys/clock.h> #include <sys/sysctl.h> #include <dev/ofw/ofw_bus.h> @@ -55,16 +56,27 @@ __FBSDID("$FreeBSD$"); #include <dev/adb/adb.h> +#include "clock_if.h" #include "pmuvar.h" #include "viareg.h" /* - * MacIO interface + * Bus interface */ static int pmu_probe(device_t); static int pmu_attach(device_t); static int pmu_detach(device_t); +/* + * Clock interface + */ +static int pmu_gettime(device_t dev, struct timespec *ts); +static int pmu_settime(device_t dev, struct timespec *ts); + +/* + * ADB Interface + */ + static u_int pmu_adb_send(device_t dev, u_char command_byte, int len, u_char *data, u_char poll); static u_int pmu_adb_autopoll(device_t dev, uint16_t mask); @@ -110,6 +122,10 @@ static device_method_t pmu_methods[] = { DEVMETHOD(adb_hb_controller_poll, pmu_poll), DEVMETHOD(adb_hb_set_autopoll_mask, pmu_adb_autopoll), + /* Clock interface */ + DEVMETHOD(clock_gettime, pmu_gettime), + DEVMETHOD(clock_settime, pmu_settime), + { 0, 0 }, }; @@ -453,6 +469,12 @@ pmu_attach(device_t dev) sc->sc_leddev = led_create(pmu_set_sleepled, sc, "sleepled"); + /* + * Register RTC + */ + + clock_register(dev, 1000); + return (bus_generic_attach(dev)); } @@ -926,3 +948,38 @@ pmu_battquery_sysctl(SYSCTL_HANDLER_ARGS) return (error); } +#define DIFF19041970 2082844800 + +static int +pmu_gettime(device_t dev, struct timespec *ts) +{ + struct pmu_softc *sc = device_get_softc(dev); + uint8_t resp[16]; + uint32_t sec; + + mtx_lock(&sc->sc_mutex); + pmu_send(sc, PMU_READ_RTC, 0, NULL, 16, resp); + mtx_unlock(&sc->sc_mutex); + + memcpy(&sec, &resp[1], 4); + ts->tv_sec = sec - DIFF19041970; + ts->tv_nsec = 0; + + return (0); +} + +static int +pmu_settime(device_t dev, struct timespec *ts) +{ + struct pmu_softc *sc = device_get_softc(dev); + uint32_t sec; + + sec = ts->tv_sec + DIFF19041970; + + mtx_lock(&sc->sc_mutex); + pmu_send(sc, PMU_SET_RTC, sizeof(sec), (uint8_t *)&sec, 0, NULL); + mtx_unlock(&sc->sc_mutex); + + return (0); +} + diff --git a/sys/powerpc/powermac/smu.c b/sys/powerpc/powermac/smu.c index 6754b3ba7d1d..100187678810 100644 --- a/sys/powerpc/powermac/smu.c +++ b/sys/powerpc/powermac/smu.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/conf.h> #include <sys/cpu.h> +#include <sys/clock.h> #include <sys/ctype.h> #include <sys/kernel.h> #include <sys/kthread.h> @@ -51,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/ofw_bus.h> #include <powerpc/powermac/macgpiovar.h> +#include "clock_if.h" + struct smu_cmd { volatile uint8_t cmd; uint8_t len; @@ -140,6 +143,10 @@ static int smu_attach(device_t); static void smu_cpufreq_pre_change(device_t, const struct cf_level *level); static void smu_cpufreq_post_change(device_t, const struct cf_level *level); +/* clock interface */ +static int smu_gettime(device_t dev, struct timespec *ts); +static int smu_settime(device_t dev, struct timespec *ts); + /* utility functions */ static int smu_run_cmd(device_t dev, struct smu_cmd *cmd, int wait); static int smu_get_datablock(device_t dev, int8_t id, uint8_t *buf, @@ -160,6 +167,10 @@ static device_method_t smu_methods[] = { /* Device interface */ DEVMETHOD(device_probe, smu_probe), DEVMETHOD(device_attach, smu_attach), + + /* Clock interface */ + DEVMETHOD(clock_gettime, smu_gettime), + DEVMETHOD(clock_settime, smu_settime), { 0, 0 }, }; @@ -192,6 +203,9 @@ MALLOC_DEFINE(M_SMU, "smu", "SMU Sensor Information"); #define SMU_PWR_GET_POWERUP 0x00 #define SMU_PWR_SET_POWERUP 0x01 #define SMU_PWR_CLR_POWERUP 0x02 +#define SMU_RTC 0x8e +#define SMU_RTC_GET 0x81 +#define SMU_RTC_SET 0x80 /* Power event types */ #define SMU_WAKEUP_KEYPRESS 0x01 @@ -349,6 +363,11 @@ smu_attach(device_t dev) powerpc_config_intr(rman_get_start(sc->sc_doorbellirq), INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); + /* + * Connect RTC interface. + */ + clock_register(dev, 1000); + return (0); } @@ -1043,3 +1062,51 @@ smu_server_mode(SYSCTL_HANDLER_ARGS) return (smu_run_cmd(smu, &cmd, 1)); } +static int +smu_gettime(device_t dev, struct timespec *ts) +{ + struct smu_cmd cmd; + struct clocktime ct; + + cmd.cmd = SMU_RTC; + cmd.len = 1; + cmd.data[0] = SMU_RTC_GET; + + if (smu_run_cmd(dev, &cmd, 1) != 0) + return (ENXIO); + + ct.nsec = 0; + ct.sec = bcd2bin(cmd.data[0]); + ct.min = bcd2bin(cmd.data[1]); + ct.hour = bcd2bin(cmd.data[2]); + ct.dow = bcd2bin(cmd.data[3]); + ct.day = bcd2bin(cmd.data[4]); + ct.mon = bcd2bin(cmd.data[5]); + ct.year = bcd2bin(cmd.data[6]) + 2000; + + return (clock_ct_to_ts(&ct, ts)); +} + +static int +smu_settime(device_t dev, struct timespec *ts) +{ + struct smu_cmd cmd; + struct clocktime ct; + + cmd.cmd = SMU_RTC; + cmd.len = 8; + cmd.data[0] = SMU_RTC_SET; + + clock_ts_to_ct(ts, &ct); + + cmd.data[1] = bin2bcd(ct.sec); + cmd.data[2] = bin2bcd(ct.min); + cmd.data[3] = bin2bcd(ct.hour); + cmd.data[4] = bin2bcd(ct.dow); + cmd.data[5] = bin2bcd(ct.day); + cmd.data[6] = bin2bcd(ct.mon); + cmd.data[7] = bin2bcd(ct.year - 2000); + + return (smu_run_cmd(dev, &cmd, 1)); +} + |