1 /* $OpenBSD: sti_sgc.c,v 1.16 2003/08/21 18:03:18 mickey Exp $ */ 2 3 /* 4 * Copyright (c) 2000-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 * These cards has to be known to work so far: 34 * - HPA1991AGrayscale rev 0.02 (705/35) (byte-wide) 35 * - HPA1991AC19 rev 0.02 (715/33) (byte-wide) 36 * - HPA208LC1280 rev 8.04 (712/80) just works 37 */ 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/device.h> 42 43 #include <uvm/uvm.h> 44 45 #include <machine/bus.h> 46 #include <machine/cpu.h> 47 #include <machine/iomod.h> 48 #include <machine/autoconf.h> 49 50 #include <dev/wscons/wsdisplayvar.h> 51 #include <dev/wscons/wsconsio.h> 52 53 #include <dev/ic/stireg.h> 54 #include <dev/ic/stivar.h> 55 56 #include <hppa/dev/cpudevs.h> 57 58 #define STI_MEMSIZE 0x2000000 59 #define STI_ROMSIZE 0x8000 60 #define STI_ID_FDDI 0x280b31af /* Medusa FDDI ROM id */ 61 62 /* gecko optional graphics */ 63 #define STI_GOPT1_REV 0x17 64 #define STI_GOPT2_REV 0x70 65 66 /* internal EG */ 67 #define STI_INEG_REV 0x60 68 #define STI_INEG_PROM 0xf0011000 69 70 int sti_sgc_probe(struct device *, void *, void *); 71 void sti_sgc_attach(struct device *, struct device *, void *); 72 73 struct cfattach sti_sgc_ca = { 74 sizeof(struct sti_softc), sti_sgc_probe, sti_sgc_attach 75 }; 76 77 struct cfattach sti_phantom_ca = { 78 sizeof(struct sti_softc), sti_sgc_probe, sti_sgc_attach 79 }; 80 81 /* 82 * Locate STI ROM. 83 * On some machines it may not be part of the HPA space. 84 */ 85 paddr_t 86 sti_sgc_getrom(int unit, struct confargs *ca) 87 { 88 paddr_t rom = PAGE0->pd_resv2[1]; 89 90 if (unit) { 91 if (ca->ca_type.iodc_sv_model == HPPA_FIO_GSGC && 92 (ca->ca_type.iodc_revision == STI_GOPT1_REV || 93 ca->ca_type.iodc_revision == STI_GOPT2_REV)) 94 /* these two share the onboard's prom */ ; 95 else 96 rom = 0; 97 } 98 99 if (rom < HPPA_IOBEGIN) { 100 if (unit == 0 && 101 ca->ca_type.iodc_sv_model == HPPA_FIO_GSGC && 102 ca->ca_type.iodc_revision == STI_INEG_REV) 103 rom = STI_INEG_PROM; 104 else 105 rom = ca->ca_hpa; 106 } 107 108 return (rom); 109 } 110 111 int 112 sti_sgc_probe(parent, match, aux) 113 struct device *parent; 114 void *match, *aux; 115 { 116 struct cfdata *cf = match; 117 struct confargs *ca = aux; 118 bus_space_handle_t romh; 119 paddr_t rom; 120 u_int32_t id; 121 u_char devtype; 122 int rv = 0, romunmapped = 0; 123 124 if (ca->ca_type.iodc_type != HPPA_TYPE_FIO) 125 return (0); 126 127 /* these can only be graphics anyway */ 128 if (ca->ca_type.iodc_sv_model == HPPA_FIO_GSGC) 129 return (1); 130 131 /* these need futher checking for the graphics id */ 132 if (ca->ca_type.iodc_sv_model != HPPA_FIO_SGC) 133 return 0; 134 135 rom = sti_sgc_getrom(cf->cf_unit, ca); 136 #ifdef STIDEBUG 137 printf ("sti: hpa=%x, rom=%x\n", ca->ca_hpa, rom); 138 #endif 139 140 /* if it does not map, probably part of the lasi space */ 141 if ((rv = bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &romh))) { 142 #ifdef STIDEBUG 143 printf ("sti: cannot map rom space (%d)\n", rv); 144 #endif 145 if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) { 146 romh = rom; 147 romunmapped++; 148 } else { 149 /* in this case i have no freaking idea */ 150 return 0; 151 } 152 } 153 154 #ifdef STIDEBUG 155 printf("sti: romh=%x\n", romh); 156 #endif 157 158 devtype = bus_space_read_1(ca->ca_iot, romh, 3); 159 160 #ifdef STIDEBUG 161 printf("sti: devtype=%d\n", devtype); 162 #endif 163 rv = 1; 164 switch (devtype) { 165 case STI_DEVTYPE4: 166 id = bus_space_read_4(ca->ca_iot, romh, 0x8); 167 break; 168 case STI_DEVTYPE1: 169 id = (bus_space_read_1(ca->ca_iot, romh, 0x10 + 3) << 24) | 170 (bus_space_read_1(ca->ca_iot, romh, 0x10 + 7) << 16) | 171 (bus_space_read_1(ca->ca_iot, romh, 0x10 + 11) << 8) | 172 (bus_space_read_1(ca->ca_iot, romh, 0x10 + 15)); 173 174 break; 175 default: 176 #ifdef STIDEBUG 177 printf("sti: unknown type (%x)\n", devtype); 178 #endif 179 rv = 0; 180 } 181 182 if (rv && 183 ca->ca_type.iodc_sv_model == HPPA_FIO_SGC && id == STI_ID_FDDI) { 184 #ifdef STIDEBUG 185 printf("sti: not a graphics device\n"); 186 #endif 187 rv = 0; 188 } 189 190 if (!romunmapped) 191 bus_space_unmap(ca->ca_iot, romh, STI_ROMSIZE); 192 return (rv); 193 } 194 195 void 196 sti_sgc_attach(parent, self, aux) 197 struct device *parent, *self; 198 void *aux; 199 { 200 struct sti_softc *sc = (void *)self; 201 struct confargs *ca = aux; 202 paddr_t rom; 203 int rv; 204 205 rom = sti_sgc_getrom(sc->sc_dev.dv_cfdata->cf_unit, ca); 206 207 #ifdef STIDEBUG 208 printf("sti: hpa=%x, rom=%x\n", ca->ca_hpa, rom); 209 #endif 210 sc->memt = sc->iot = ca->ca_iot; 211 212 if ((rv = bus_space_map(ca->ca_iot, ca->ca_hpa, STI_MEMSIZE, 0, 213 &sc->ioh))) { 214 #ifdef STIDEBUG 215 printf(": cannot map io space (%d)\n", rv); 216 #endif 217 return; 218 } 219 220 /* if it does not map, probably part of the lasi space */ 221 if (rom == ca->ca_hpa) 222 sc->romh = sc->ioh; 223 else if ((rv = bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &sc->romh))) { 224 if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) 225 sc->romh = rom; 226 else { 227 #ifdef STIDEBUG 228 printf (": cannot map rom space (%d)\n", rv); 229 #endif 230 /* in this case i have no freaking idea */ 231 bus_space_unmap(ca->ca_iot, sc->ioh, STI_MEMSIZE); 232 return; 233 } 234 } 235 236 #ifdef STIDEBUG 237 printf("sti: ioh=%x, romh=%x\n", sc->ioh, sc->romh); 238 #endif 239 sc->sc_devtype = bus_space_read_1(sc->iot, sc->romh, 3); 240 if (ca->ca_hpa == (hppa_hpa_t)PAGE0->mem_cons.pz_hpa) 241 sc->sc_flags |= STI_CONSOLE; 242 sti_attach_common(sc); 243 } 244