lasi.c revision 1.17
1/* $OpenBSD: lasi.c,v 1.17 2003/08/28 15:24:19 mickey Exp $ */ 2 3/* 4 * Copyright (c) 1998-2003 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 MIND, 27 * USE, 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/reg.h> 43#include <machine/autoconf.h> 44 45#include <hppa/dev/cpudevs.h> 46 47#include <hppa/gsc/gscbusvar.h> 48 49#define LASI_IOMASK 0xfff00000 50 51struct lasi_hwr { 52 u_int32_t lasi_power; 53#define LASI_BLINK 0x01 54#define LASI_OFF 0x02 55 u_int32_t lasi_error; 56 u_int32_t lasi_version; 57 u_int32_t lasi_reset; 58 u_int32_t lasi_arbmask; 59}; 60 61struct lasi_trs { 62 u_int32_t lasi_irr; /* int requset register */ 63 u_int32_t lasi_imr; /* int mask register */ 64 u_int32_t lasi_ipr; /* int pending register */ 65 u_int32_t lasi_icr; /* int command? register */ 66 u_int32_t lasi_iar; /* int acquire? register */ 67}; 68 69struct lasi_softc { 70 struct device sc_dev; 71 struct gscbus_ic sc_ic; 72 int sc_phantomassed; 73 74 struct lasi_hwr volatile *sc_hw; 75 struct lasi_trs volatile *sc_trs; 76 struct gsc_attach_args ga; /* for deferred attach */ 77}; 78 79int lasimatch(struct device *, void *, void *); 80void lasiattach(struct device *, struct device *, void *); 81void lasi_mainbus_attach(struct device *, struct device *, void *); 82void lasi_phantomas_attach(struct device *, struct device *, void *); 83void lasi_gsc_attach(struct device *); 84 85struct cfattach lasi_mainbus_ca = { 86 sizeof(struct lasi_softc), lasimatch, lasi_mainbus_attach 87}; 88 89struct cfattach lasi_phantomas_ca = { 90 sizeof(struct lasi_softc), lasimatch, lasi_phantomas_attach 91}; 92 93struct cfdriver lasi_cd = { 94 NULL, "lasi", DV_DULL 95}; 96 97void lasi_cold_hook(int on); 98 99int 100lasimatch(parent, cfdata, aux) 101 struct device *parent; 102 void *cfdata; 103 void *aux; 104{ 105 register struct confargs *ca = aux; 106 /* register struct cfdata *cf = cfdata; */ 107 108 if (ca->ca_type.iodc_type != HPPA_TYPE_BHA || 109 ca->ca_type.iodc_sv_model != HPPA_BHA_LASI) 110 return 0; 111 112 return 1; 113} 114 115void 116lasi_mainbus_attach(parent, self, aux) 117 struct device *parent; 118 struct device *self; 119 void *aux; 120{ 121 lasiattach(parent, self, aux); 122} 123 124void 125lasi_phantomas_attach(parent, self, aux) 126 struct device *parent; 127 struct device *self; 128 void *aux; 129{ 130 struct lasi_softc *sc = (struct lasi_softc *)self; 131 132 sc->sc_phantomassed = 1; 133 lasiattach(parent, self, aux); 134} 135 136void 137lasiattach(parent, self, aux) 138 struct device *parent; 139 struct device *self; 140 void *aux; 141{ 142 struct lasi_softc *sc = (struct lasi_softc *)self; 143 struct confargs *ca = aux; 144 bus_space_handle_t ioh; 145 int s, in; 146 147 if (bus_space_map(ca->ca_iot, ca->ca_hpa + 0xc000, 148 IOMOD_HPASIZE, 0, &ioh)) { 149 printf(": can't map IO space\n"); 150 return; 151 } 152 153 sc->sc_trs = (struct lasi_trs *)ca->ca_hpa; 154 sc->sc_hw = (struct lasi_hwr *)(ca->ca_hpa + 0xc000); 155 156 /* XXX should we reset the chip here? */ 157 158 printf(": rev %d.%d\n", (sc->sc_hw->lasi_version & 0xf0) >> 4, 159 sc->sc_hw->lasi_version & 0xf); 160 161 /* interrupts guts */ 162 s = splhigh(); 163 sc->sc_trs->lasi_iar = cpu_gethpa(0) | (31 - ca->ca_irq); 164 sc->sc_trs->lasi_icr = 0; 165 sc->sc_trs->lasi_imr = ~0U; 166 in = sc->sc_trs->lasi_irr; 167 sc->sc_trs->lasi_imr = 0; 168 splx(s); 169 170 sc->sc_ic.gsc_type = gsc_lasi; 171 sc->sc_ic.gsc_dv = sc; 172 sc->sc_ic.gsc_base = sc->sc_trs; 173 174#ifdef USELEDS 175 /* figure out the leds address */ 176 switch (cpu_hvers) { 177 case HPPA_BOARD_HP712_60: 178 case HPPA_BOARD_HP712_80: 179 case HPPA_BOARD_HP712_100: 180 case HPPA_BOARD_HP743I_64: 181 case HPPA_BOARD_HP743I_100: 182 case HPPA_BOARD_HP712_120: 183 break; /* only has one led. works different */ 184 185 case HPPA_BOARD_HP715_64: 186 case HPPA_BOARD_HP715_80: 187 case HPPA_BOARD_HP715_100: 188 case HPPA_BOARD_HP715_100XC: 189 case HPPA_BOARD_HP725_100: 190 case HPPA_BOARD_HP725_120: 191 if (bus_space_map(ca->ca_iot, ca->ca_hpa - 0x20000, 192 4, 0, (bus_space_handle_t *)&machine_ledaddr)) 193 machine_ledaddr = NULL; 194 machine_ledword = 1; 195 break; 196 197 case HPPA_BOARD_HP800_A180C: 198 case HPPA_BOARD_HP778_B180L: 199 case HPPA_BOARD_HP780_C100: 200 case HPPA_BOARD_HP780_C110: 201 case HPPA_BOARD_HP779_C132L: 202 case HPPA_BOARD_HP779_C160L: 203 case HPPA_BOARD_HP779_C180L: 204 case HPPA_BOARD_HP779_C160L1: 205 case HPPA_BOARD_HP770_J200: 206 case HPPA_BOARD_HP770_J210: 207 if (bus_space_map(ca->ca_iot, 0xf0190000, 208 4, 0, (bus_space_handle_t *)&machine_ledaddr)) 209 machine_ledaddr = NULL; 210 machine_ledword = 1; 211 break; 212 213 default: 214 machine_ledaddr = (u_int8_t *)sc->sc_hw; 215 machine_ledword = 1; 216 break; 217 } 218#endif 219 220 sc->ga.ga_ca = *ca; /* clone from us */ 221 if (!sc->sc_phantomassed) { 222 sc->ga.ga_dp.dp_bc[0] = sc->ga.ga_dp.dp_bc[1]; 223 sc->ga.ga_dp.dp_bc[1] = sc->ga.ga_dp.dp_bc[2]; 224 sc->ga.ga_dp.dp_bc[2] = sc->ga.ga_dp.dp_bc[3]; 225 sc->ga.ga_dp.dp_bc[3] = sc->ga.ga_dp.dp_bc[4]; 226 sc->ga.ga_dp.dp_bc[4] = sc->ga.ga_dp.dp_bc[5]; 227 sc->ga.ga_dp.dp_bc[5] = sc->ga.ga_dp.dp_mod; 228 sc->ga.ga_dp.dp_mod = 0; 229 } 230 if (sc->sc_dev.dv_unit) 231 config_defer(self, lasi_gsc_attach); 232 else { 233 extern void (*cold_hook)(int); 234 235 lasi_gsc_attach(self); 236 /* could be already set by power(4) */ 237 if (!cold_hook) 238 cold_hook = lasi_cold_hook; 239 } 240} 241 242void 243lasi_gsc_attach(self) 244 struct device *self; 245{ 246 struct lasi_softc *sc = (struct lasi_softc *)self; 247 248 sc->ga.ga_name = "gsc"; 249 sc->ga.ga_hpamask = LASI_IOMASK; 250 sc->ga.ga_ic = &sc->sc_ic; 251 config_found(self, &sc->ga, gscprint); 252} 253 254void 255lasi_cold_hook(on) 256 int on; 257{ 258 register struct lasi_softc *sc = lasi_cd.cd_devs[0]; 259 260 if (!sc) 261 return; 262 263 switch (on) { 264 case HPPA_COLD_COLD: 265 sc->sc_hw->lasi_power = LASI_BLINK; 266 break; 267 case HPPA_COLD_HOT: 268 sc->sc_hw->lasi_power = 0; 269 break; 270 case HPPA_COLD_OFF: 271 sc->sc_hw->lasi_power = LASI_OFF; 272 break; 273 } 274} 275