1 /* $OpenBSD: plrtc.c,v 1.2 2021/10/24 17:52:26 mpi Exp $ */ 2 3 /* 4 * Copyright (c) 2015 Jonathan Gray <jsg@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/device.h> 21 #include <sys/malloc.h> 22 #include <sys/systm.h> 23 24 #include <machine/bus.h> 25 #include <machine/fdt.h> 26 #include <dev/clock_subr.h> 27 28 #include <dev/ofw/openfirm.h> 29 #include <dev/ofw/fdt.h> 30 31 #define RTCDR 0x00 32 #define RTCMR 0x04 33 #define RTCLR 0x08 34 #define RTCCR 0x0c 35 #define RTCIMSC 0x10 36 #define RTCRIS 0x14 37 #define RTCMIS 0x18 38 #define RTCICR 0x1c 39 40 #define RTCCR_START (1 << 0) 41 42 extern todr_chip_handle_t todr_handle; 43 44 struct plrtc_softc { 45 struct device sc_dev; 46 bus_space_tag_t sc_iot; 47 bus_space_handle_t sc_ioh; 48 }; 49 50 int plrtc_match(struct device *, void *, void *); 51 void plrtc_attach(struct device *, struct device *, void *); 52 int plrtc_gettime(struct todr_chip_handle *, struct timeval *); 53 int plrtc_settime(struct todr_chip_handle *, struct timeval *); 54 55 56 const struct cfattach plrtc_ca = { 57 sizeof(struct plrtc_softc), plrtc_match, plrtc_attach 58 }; 59 60 struct cfdriver plrtc_cd = { 61 NULL, "plrtc", DV_DULL 62 }; 63 64 int 65 plrtc_gettime(todr_chip_handle_t handle, struct timeval *tv) 66 { 67 struct plrtc_softc *sc = handle->cookie; 68 uint32_t tod; 69 70 tod = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RTCDR); 71 72 tv->tv_sec = tod; 73 tv->tv_usec = 0; 74 75 return (0); 76 } 77 78 int 79 plrtc_settime(todr_chip_handle_t handle, struct timeval *tv) 80 { 81 struct plrtc_softc *sc = handle->cookie; 82 83 bus_space_write_4(sc->sc_iot, sc->sc_ioh, RTCLR, tv->tv_sec); 84 85 return (0); 86 } 87 88 int 89 plrtc_match(struct device *parent, void *match, void *aux) 90 { 91 struct fdt_attach_args *faa = aux; 92 93 return (OF_is_compatible(faa->fa_node, "arm,pl031")); 94 } 95 96 void 97 plrtc_attach(struct device *parent, struct device *self, void *aux) 98 { 99 struct fdt_attach_args *faa = aux; 100 struct plrtc_softc *sc = (struct plrtc_softc *) self; 101 todr_chip_handle_t handle; 102 103 if (faa->fa_nreg < 1) { 104 printf(": no register data\n"); 105 return; 106 } 107 108 sc->sc_iot = faa->fa_iot; 109 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 110 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 111 printf(": failed to map mem space\n"); 112 return; 113 } 114 115 handle = malloc(sizeof(struct todr_chip_handle), M_DEVBUF, 116 M_NOWAIT | M_ZERO); 117 if (handle == NULL) 118 panic("couldn't allocate todr_handle"); 119 120 handle->cookie = sc; 121 handle->todr_gettime = plrtc_gettime; 122 handle->todr_settime = plrtc_settime; 123 todr_handle = handle; 124 125 /* enable the rtc */ 126 bus_space_write_4(sc->sc_iot, sc->sc_ioh, RTCCR, RTCCR_START); 127 128 printf("\n"); 129 } 130