1 /* $OpenBSD: sysreg.c,v 1.1 2015/06/08 06:33:16 jsg 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/systm.h> 21 #include <sys/device.h> 22 #include <machine/bus.h> 23 #include <armv7/armv7/armv7var.h> 24 25 #define SYS_ID 0x00 26 #define SYS_PROCID0 0x84 27 #define SYS_PROCID1 0x88 28 #define SYS_CFGDATA 0xa0 29 #define SYS_CFGCTRL 0xa4 30 #define SYS_CFGSTAT 0xa8 31 32 #define SYS_CFG_WRITE (1 << 30) 33 #define SYS_CFG_START (1U << 31) 34 35 #define SYS_CFG_RESET 5 36 #define SYS_CFG_SHUTDOWN 8 37 #define SYS_CFG_REBOOT 9 38 39 #define SYS_CFGSTAT_COMPLETE (1 << 0) 40 #define SYS_CFGSTAT_ERROR (1 << 1) 41 42 struct sysreg_softc { 43 struct device sc_dev; 44 bus_space_tag_t sc_iot; 45 bus_space_handle_t sc_ioh; 46 }; 47 48 struct sysreg_softc *sysreg_sc; 49 50 void sysreg_attach(struct device *, struct device *, void *); 51 void sysreg_reset(void); 52 53 struct cfattach sysreg_ca = { 54 sizeof (struct sysreg_softc), NULL, sysreg_attach 55 }; 56 57 struct cfdriver sysreg_cd = { 58 NULL, "sysreg", DV_DULL 59 }; 60 61 void 62 sysreg_attach(struct device *parent, struct device *self, void *args) 63 { 64 struct armv7_attach_args *aa = args; 65 struct sysreg_softc *sc = (struct sysreg_softc *)self; 66 uint32_t id; 67 68 sc->sc_iot = aa->aa_iot; 69 if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, 70 aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) 71 panic(": bus_space_map failed!"); 72 sysreg_sc = sc; 73 74 id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SYS_ID); 75 printf(": ID 0x%x", id); 76 77 id = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SYS_PROCID0); 78 printf(" PROCID0 0x%x\n", id); 79 } 80 81 void 82 sysconf_function(struct sysreg_softc *sc, int function) 83 { 84 int dcc, site, position, device; 85 86 dcc = 0; 87 site = 0; 88 position = 0; 89 device = 0; 90 91 bus_space_write_4(sc->sc_iot, sc->sc_ioh, SYS_CFGSTAT, 0); 92 bus_space_write_4(sc->sc_iot, sc->sc_ioh, SYS_CFGCTRL, 93 SYS_CFG_START | SYS_CFG_WRITE | 94 (dcc << 26) | (function << 20) | (site << 16) | 95 (position << 12) | device); 96 97 while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SYS_CFGSTAT) & 98 SYS_CFGSTAT_COMPLETE) == 0); 99 100 if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SYS_CFGSTAT) & 101 SYS_CFGSTAT_ERROR) 102 printf("SYS_CFGSTAT error\n"); 103 } 104 105 void 106 sysconf_reboot(void) 107 { 108 struct sysreg_softc *sc = sysreg_sc; 109 110 if (sc == NULL) 111 return; 112 113 sysconf_function(sc, SYS_CFG_REBOOT); 114 } 115 116 void 117 sysconf_shutdown(void) 118 { 119 struct sysreg_softc *sc = sysreg_sc; 120 121 if (sc == NULL) 122 return; 123 124 sysconf_function(sc, SYS_CFG_SHUTDOWN); 125 } 126