1 /* $OpenBSD: lasi.c,v 1.4 2001/06/09 03:57:19 mickey Exp $ */ 2 3 /* 4 * Copyright (c) 1998,1999 Michael Shalayeff 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Michael Shalayeff. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #undef LASIDEBUG 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/device.h> 38 #include <sys/reboot.h> 39 40 #include <machine/bus.h> 41 #include <machine/iomod.h> 42 #include <machine/autoconf.h> 43 44 #include <hppa/dev/cpudevs.h> 45 46 #include <hppa/gsc/gscbusvar.h> 47 48 struct lasi_hwr { 49 u_int32_t lasi_power; 50 u_int32_t lasi_error; 51 u_int32_t lasi_version; 52 u_int32_t lasi_reset; 53 u_int32_t lasi_arbmask; 54 }; 55 56 struct lasi_trs { 57 u_int32_t lasi_irr; /* int requset register */ 58 u_int32_t lasi_imr; /* int mask register */ 59 u_int32_t lasi_ipr; /* int pending register */ 60 u_int32_t lasi_icr; /* int command? register */ 61 u_int32_t lasi_iar; /* int acquire? register */ 62 }; 63 64 struct lasi_softc { 65 struct device sc_dev; 66 struct gscbus_ic sc_ic; 67 68 struct lasi_hwr volatile *sc_hw; 69 struct lasi_trs volatile *sc_trs; 70 }; 71 72 int lasimatch __P((struct device *, void *, void *)); 73 void lasiattach __P((struct device *, struct device *, void *)); 74 75 struct cfattach lasi_ca = { 76 sizeof(struct lasi_softc), lasimatch, lasiattach 77 }; 78 79 struct cfdriver lasi_cd = { 80 NULL, "lasi", DV_DULL 81 }; 82 83 void lasi_intr_establish __P((void *v, u_int32_t mask)); 84 void lasi_intr_disestablish __P((void *v, u_int32_t mask)); 85 u_int32_t lasi_intr_check __P((void *v)); 86 void lasi_intr_ack __P((void *v, u_int32_t mask)); 87 88 89 int 90 lasimatch(parent, cfdata, aux) 91 struct device *parent; 92 void *cfdata; 93 void *aux; 94 { 95 register struct confargs *ca = aux; 96 /* register struct cfdata *cf = cfdata; */ 97 98 if (ca->ca_type.iodc_type != HPPA_TYPE_BHA || 99 ca->ca_type.iodc_sv_model != HPPA_BHA_LASI) 100 return 0; 101 102 return 1; 103 } 104 105 void 106 lasiattach(parent, self, aux) 107 struct device *parent; 108 struct device *self; 109 void *aux; 110 { 111 register struct confargs *ca = aux; 112 register struct lasi_softc *sc = (struct lasi_softc *)self; 113 struct gsc_attach_args ga; 114 bus_space_handle_t ioh; 115 int s, in; 116 117 if (bus_space_map(ca->ca_iot, ca->ca_hpa + 0xc000, 118 IOMOD_HPASIZE, 0, &ioh)) { 119 #ifdef DEBUG 120 printf("lasiattach: can't map IO space\n"); 121 #endif 122 return; 123 } 124 125 sc->sc_trs = (struct lasi_trs *)ca->ca_hpa; 126 sc->sc_hw = (struct lasi_hwr *)(ca->ca_hpa + 0xc000); 127 128 /* XXX should we reset the chip here? */ 129 130 printf (": rev %d.%d\n", (sc->sc_hw->lasi_version & 0xf0) >> 4, 131 sc->sc_hw->lasi_version & 0xf); 132 133 /* interrupts guts */ 134 s = splhigh(); 135 sc->sc_trs->lasi_iar = cpu_gethpa(0) | (31 - ca->ca_irq); 136 sc->sc_trs->lasi_icr = 0; 137 sc->sc_trs->lasi_imr = ~0U; 138 in = sc->sc_trs->lasi_irr; 139 sc->sc_trs->lasi_imr = 0; 140 splx(s); 141 142 sc->sc_ic.gsc_type = gsc_lasi; 143 sc->sc_ic.gsc_dv = sc; 144 sc->sc_ic.gsc_intr_establish = lasi_intr_establish; 145 sc->sc_ic.gsc_intr_disestablish = lasi_intr_disestablish; 146 sc->sc_ic.gsc_intr_check = lasi_intr_check; 147 sc->sc_ic.gsc_intr_ack = lasi_intr_ack; 148 149 ga.ga_ca = *ca; /* clone from us */ 150 ga.ga_name = "gsc"; 151 ga.ga_ic = &sc->sc_ic; 152 config_found(self, &ga, gscprint); 153 } 154 155 void 156 lasi_intr_establish(v, mask) 157 void *v; 158 u_int32_t mask; 159 { 160 register struct lasi_softc *sc = v; 161 162 sc->sc_trs->lasi_imr |= mask; 163 } 164 165 void 166 lasi_intr_disestablish(v, mask) 167 void *v; 168 u_int32_t mask; 169 { 170 register struct lasi_softc *sc = v; 171 172 sc->sc_trs->lasi_imr &= ~mask; 173 } 174 175 u_int32_t 176 lasi_intr_check(v) 177 void *v; 178 { 179 register struct lasi_softc *sc = v; 180 register u_int32_t irr, imr, ipr; 181 182 imr = sc->sc_trs->lasi_imr; 183 ipr = sc->sc_trs->lasi_ipr; 184 irr = sc->sc_trs->lasi_irr; 185 sc->sc_trs->lasi_imr = 0; 186 sc->sc_trs->lasi_imr = imr &= ~irr; 187 188 #ifdef LASIDEBUG 189 printf ("%s: imr=0x%x, irr=0x%x, ipr=0x%x, iar=0x%x, icr=0x%x\n", 190 sc->sc_dev.dv_xname, imr, irr, ipr, 191 sc->sc_trs->lasi_iar, sc->sc_trs->lasi_icr); 192 #endif 193 194 return irr; 195 } 196 197 void 198 lasi_intr_ack(v, mask) 199 void *v; 200 u_int32_t mask; 201 { 202 register struct lasi_softc *sc = v; 203 204 sc->sc_trs->lasi_imr |= mask; 205 } 206