1 /* $NetBSD: jensenio.c,v 1.3 2001/07/27 00:25:19 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Driver for the Jensen I/O bus. 41 * 42 * The Jensen I/O `bus' is comprised of two things: 43 * 44 * - VLSI VL82C106 junk I/O chip 45 * - Intel EISA bus interface 46 * 47 * Access to the 82C106 is different than to the rest of EISA space, even 48 * though it is a single address space. 49 */ 50 51 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 52 53 __KERNEL_RCSID(0, "$NetBSD: jensenio.c,v 1.3 2001/07/27 00:25:19 thorpej Exp $"); 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/device.h> 58 59 #include <machine/autoconf.h> 60 61 #include <dev/eisa/eisavar.h> 62 63 #include <dev/isa/isareg.h> 64 #include <dev/isa/isavar.h> 65 66 #include <alpha/jensenio/jensenioreg.h> 67 #include <alpha/jensenio/jenseniovar.h> 68 69 #include "eisa.h" 70 71 /* 72 * The devices built-in to the VLSI VL82C106 junk I/O chip. 73 */ 74 const struct jensenio_dev { 75 const char *jd_name; /* device name */ 76 bus_addr_t jd_ioaddr; /* I/O space address */ 77 int jd_irq[2]; /* Jensen IRQs */ 78 } jensenio_devs[] = { 79 { "pckbc", IO_KBD, { 0x980, 0x990 } }, 80 { "com", IO_COM1, { 0x900, -1 } }, 81 { "com", IO_COM2, { 0x920, -1 } }, 82 { "lpt", IO_LPT3, { 1, -1 } }, 83 { "mcclock", 0x170, { -1, -1 } }, 84 { NULL, 0, { -1, -1 } }, 85 }; 86 87 int jensenio_match(struct device *, struct cfdata *, void *); 88 void jensenio_attach(struct device *, struct device *, void *); 89 90 struct cfattach jensenio_ca = { 91 sizeof(struct device), jensenio_match, jensenio_attach 92 }; 93 94 int jensenio_print(void *, const char *); 95 int jensenio_submatch(struct device *, struct cfdata *, void *); 96 97 int jensenio_attached; 98 99 struct jensenio_config jensenio_configuration; 100 101 void jensenio_eisa_attach_hook(struct device *, struct device *, 102 struct eisabus_attach_args *); 103 int jensenio_eisa_maxslots(void *); 104 105 void jensenio_isa_attach_hook(struct device *, struct device *, 106 struct isabus_attach_args *); 107 108 /* 109 * Set up the Jensen's function pointers. 110 */ 111 void 112 jensenio_init(struct jensenio_config *jcp, int mallocsafe) 113 { 114 115 /* 116 * Initialize the Host Address Extension register to 0 117 * (the firmware should have already done this). We will 118 * disallow mapping of any device who's address would 119 * require a non-0 HAE. This should be safe as the final 120 * draft of the Jensen system specification states that 121 * applications should follow this little rule. 122 * 123 * There's a good reason for this; actually using HAE would 124 * require a mutex around *every* EISA cycle! Gross! 125 */ 126 REGVAL(JENSEN_HAE) = 0; 127 alpha_mb(); 128 129 if (jcp->jc_initted == 0) { 130 /* don't do these twice since they set up extents */ 131 jensenio_bus_io_init(&jcp->jc_eisa_iot, jcp); 132 jensenio_bus_intio_init(&jcp->jc_internal_iot, jcp); 133 jensenio_bus_mem_init(&jcp->jc_eisa_memt, jcp); 134 } 135 jcp->jc_mallocsafe = mallocsafe; 136 } 137 138 int 139 jensenio_match(struct device *parent, struct cfdata *cf, void *aux) 140 { 141 struct mainbus_attach_args *ma = aux; 142 143 if (strcmp(ma->ma_name, cf->cf_driver->cd_name) != 0) 144 return (0); 145 146 /* There can be only one. */ 147 if (jensenio_attached) 148 return (0); 149 150 return (1); 151 } 152 153 void 154 jensenio_attach(struct device *parent, struct device *self, void *aux) 155 { 156 struct jensenio_attach_args ja; 157 struct jensenio_config *jcp = &jensenio_configuration; 158 int i; 159 160 printf("\n"); 161 162 jensenio_attached = 1; 163 164 /* 165 * Done once at console init time, but we might need to do 166 * additional work this time. 167 */ 168 jensenio_init(jcp, 1); 169 170 /* 171 * Initialize DMA. 172 */ 173 jensenio_dma_init(jcp); 174 175 /* 176 * Initialize interrupts. 177 */ 178 jensenio_intr_init(jcp); 179 180 /* 181 * First attach all of the built-in devices. 182 */ 183 for (i = 0; jensenio_devs[i].jd_name != NULL; i++) { 184 ja.ja_name = jensenio_devs[i].jd_name; 185 ja.ja_ioaddr = jensenio_devs[i].jd_ioaddr; 186 ja.ja_irq[0] = jensenio_devs[i].jd_irq[0]; 187 ja.ja_irq[1] = jensenio_devs[i].jd_irq[1]; 188 189 ja.ja_iot = &jcp->jc_internal_iot; 190 ja.ja_ec = &jcp->jc_ec; 191 192 (void) config_found_sm(self, &ja, jensenio_print, 193 jensenio_submatch); 194 } 195 196 /* 197 * Attach the EISA bus. 198 */ 199 jcp->jc_ec.ec_attach_hook = jensenio_eisa_attach_hook; 200 jcp->jc_ec.ec_maxslots = jensenio_eisa_maxslots; 201 202 ja.ja_eisa.eba_busname = "eisa"; 203 ja.ja_eisa.eba_iot = &jcp->jc_eisa_iot; 204 ja.ja_eisa.eba_memt = &jcp->jc_eisa_memt; 205 ja.ja_eisa.eba_dmat = &jcp->jc_dmat_eisa; 206 ja.ja_eisa.eba_ec = &jcp->jc_ec; 207 (void) config_found(self, &ja.ja_eisa, jensenio_print); 208 209 /* 210 * Attach the ISA bus. 211 */ 212 jcp->jc_ic.ic_attach_hook = jensenio_isa_attach_hook; 213 214 ja.ja_isa.iba_busname = "isa"; 215 ja.ja_isa.iba_iot = &jcp->jc_eisa_iot; 216 ja.ja_isa.iba_memt = &jcp->jc_eisa_memt; 217 ja.ja_isa.iba_dmat = &jcp->jc_dmat_isa; 218 ja.ja_isa.iba_ic = &jcp->jc_ic; 219 (void) config_found(self, &ja.ja_isa, jensenio_print); 220 } 221 222 int 223 jensenio_submatch(struct device *parent, struct cfdata *cf, void *aux) 224 { 225 struct jensenio_attach_args *ja = aux; 226 227 /* 228 * Skip the locator song-and-dance if we're attaching the 229 * EISA or ISA layer. 230 */ 231 if (strcmp(ja->ja_name, "eisa") == 0 || 232 strcmp(ja->ja_name, "isa") == 0) 233 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 234 235 if (cf->cf_loc[JENSENIOCF_PORT] != JENSENIOCF_PORT_DEFAULT && 236 cf->cf_loc[JENSENIOCF_PORT] != ja->ja_ioaddr) 237 return (0); 238 239 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 240 } 241 242 int 243 jensenio_print(void *aux, const char *pnp) 244 { 245 struct jensenio_attach_args *ja = aux; 246 247 if (pnp != NULL) 248 printf("%s at %s", ja->ja_name, pnp); 249 250 /* 251 * Skip the locator song-and-dance if we're attaching the 252 * EISA or ISA layer. 253 */ 254 if (strcmp(ja->ja_name, "eisa") != 0 && 255 strcmp(ja->ja_name, "isa") != 0) 256 printf(" port 0x%lx", ja->ja_ioaddr); 257 258 return (UNCONF); 259 } 260 261 void 262 jensenio_eisa_attach_hook(struct device *parent, struct device *self, 263 struct eisabus_attach_args *eba) 264 { 265 266 #if NEISA > 0 267 /* 268 * Jensen's EISA config info is sparse, and is mapped at a 269 * different location that on other EISA systems. 270 */ 271 eisa_config_stride = 0x200; 272 eisa_config_addr = JENSEN_FEPROM1; 273 eisa_init(); 274 #endif 275 } 276 277 int 278 jensenio_eisa_maxslots(void *v) 279 { 280 281 return (16); /* as good a number as any. only 8, maybe? */ 282 } 283 284 void 285 jensenio_isa_attach_hook(struct device *parent, struct device *self, 286 struct isabus_attach_args *iba) 287 { 288 289 /* Nothing to do. */ 290 } 291