1 /* $NetBSD: jensenio.c,v 1.8 2003/01/01 00:39: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.8 2003/01/01 00:39: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 CFATTACH_DECL(jensenio, sizeof(struct device), 91 jensenio_match, jensenio_attach, NULL, NULL); 92 93 int jensenio_print(void *, const char *); 94 int jensenio_submatch(struct device *, struct cfdata *, void *); 95 96 int jensenio_attached; 97 98 struct jensenio_config jensenio_configuration; 99 100 void jensenio_eisa_attach_hook(struct device *, struct device *, 101 struct eisabus_attach_args *); 102 int jensenio_eisa_maxslots(void *); 103 104 void jensenio_isa_attach_hook(struct device *, struct device *, 105 struct isabus_attach_args *); 106 107 /* 108 * Set up the Jensen's function pointers. 109 */ 110 void 111 jensenio_init(struct jensenio_config *jcp, int mallocsafe) 112 { 113 114 /* 115 * Initialize the Host Address Extension register to 0 116 * (the firmware should have already done this). We will 117 * disallow mapping of any device who's address would 118 * require a non-0 HAE. This should be safe as the final 119 * draft of the Jensen system specification states that 120 * applications should follow this little rule. 121 * 122 * There's a good reason for this; actually using HAE would 123 * require a mutex around *every* EISA cycle! Gross! 124 */ 125 REGVAL(JENSEN_HAE) = 0; 126 alpha_mb(); 127 128 if (jcp->jc_initted == 0) { 129 /* don't do these twice since they set up extents */ 130 jensenio_bus_io_init(&jcp->jc_eisa_iot, jcp); 131 jensenio_bus_intio_init(&jcp->jc_internal_iot, jcp); 132 jensenio_bus_mem_init(&jcp->jc_eisa_memt, jcp); 133 } 134 jcp->jc_mallocsafe = mallocsafe; 135 } 136 137 int 138 jensenio_match(struct device *parent, struct cfdata *cf, void *aux) 139 { 140 struct mainbus_attach_args *ma = aux; 141 142 if (strcmp(ma->ma_name, cf->cf_name) != 0) 143 return (0); 144 145 /* There can be only one. */ 146 if (jensenio_attached) 147 return (0); 148 149 return (1); 150 } 151 152 void 153 jensenio_attach(struct device *parent, struct device *self, void *aux) 154 { 155 struct jensenio_attach_args ja; 156 struct jensenio_config *jcp = &jensenio_configuration; 157 int i; 158 159 printf("\n"); 160 161 jensenio_attached = 1; 162 163 /* 164 * Done once at console init time, but we might need to do 165 * additional work this time. 166 */ 167 jensenio_init(jcp, 1); 168 169 /* 170 * Initialize DMA. 171 */ 172 jensenio_dma_init(jcp); 173 174 /* 175 * Initialize interrupts. 176 */ 177 jensenio_intr_init(jcp); 178 179 /* 180 * First attach all of the built-in devices. 181 */ 182 for (i = 0; jensenio_devs[i].jd_name != NULL; i++) { 183 ja.ja_name = jensenio_devs[i].jd_name; 184 ja.ja_ioaddr = jensenio_devs[i].jd_ioaddr; 185 ja.ja_irq[0] = jensenio_devs[i].jd_irq[0]; 186 ja.ja_irq[1] = jensenio_devs[i].jd_irq[1]; 187 188 ja.ja_iot = &jcp->jc_internal_iot; 189 ja.ja_ec = &jcp->jc_ec; 190 191 (void) config_found_sm(self, &ja, jensenio_print, 192 jensenio_submatch); 193 } 194 195 /* 196 * Attach the EISA bus. 197 */ 198 jcp->jc_ec.ec_attach_hook = jensenio_eisa_attach_hook; 199 jcp->jc_ec.ec_maxslots = jensenio_eisa_maxslots; 200 201 ja.ja_eisa.eba_busname = "eisa"; 202 ja.ja_eisa.eba_iot = &jcp->jc_eisa_iot; 203 ja.ja_eisa.eba_memt = &jcp->jc_eisa_memt; 204 ja.ja_eisa.eba_dmat = &jcp->jc_dmat_eisa; 205 ja.ja_eisa.eba_ec = &jcp->jc_ec; 206 (void) config_found(self, &ja.ja_eisa, jensenio_print); 207 208 /* 209 * Attach the ISA bus. 210 */ 211 jcp->jc_ic.ic_attach_hook = jensenio_isa_attach_hook; 212 213 ja.ja_isa.iba_busname = "isa"; 214 ja.ja_isa.iba_iot = &jcp->jc_eisa_iot; 215 ja.ja_isa.iba_memt = &jcp->jc_eisa_memt; 216 ja.ja_isa.iba_dmat = &jcp->jc_dmat_isa; 217 ja.ja_isa.iba_ic = &jcp->jc_ic; 218 (void) config_found(self, &ja.ja_isa, jensenio_print); 219 } 220 221 int 222 jensenio_submatch(struct device *parent, struct cfdata *cf, void *aux) 223 { 224 struct jensenio_attach_args *ja = aux; 225 226 /* 227 * Skip the locator song-and-dance if we're attaching the 228 * EISA or ISA layer. 229 */ 230 if (strcmp(ja->ja_name, "eisa") == 0 || 231 strcmp(ja->ja_name, "isa") == 0) 232 return (config_match(parent, cf, aux)); 233 234 if (cf->cf_loc[JENSENIOCF_PORT] != JENSENIOCF_PORT_DEFAULT && 235 cf->cf_loc[JENSENIOCF_PORT] != ja->ja_ioaddr) 236 return (0); 237 238 return (config_match(parent, cf, aux)); 239 } 240 241 int 242 jensenio_print(void *aux, const char *pnp) 243 { 244 struct jensenio_attach_args *ja = aux; 245 246 if (pnp != NULL) 247 aprint_normal("%s at %s", ja->ja_name, pnp); 248 249 /* 250 * Skip the locator song-and-dance if we're attaching the 251 * EISA or ISA layer. 252 */ 253 if (strcmp(ja->ja_name, "eisa") != 0 && 254 strcmp(ja->ja_name, "isa") != 0) 255 aprint_normal(" port 0x%lx", ja->ja_ioaddr); 256 257 return (UNCONF); 258 } 259 260 void 261 jensenio_eisa_attach_hook(struct device *parent, struct device *self, 262 struct eisabus_attach_args *eba) 263 { 264 265 #if NEISA > 0 266 /* 267 * Jensen's EISA config info is sparse, and is mapped at a 268 * different location that on other EISA systems. 269 */ 270 eisa_config_stride = 0x200; 271 eisa_config_addr = JENSEN_FEPROM1; 272 eisa_init(); 273 #endif 274 } 275 276 int 277 jensenio_eisa_maxslots(void *v) 278 { 279 280 return (16); /* as good a number as any. only 8, maybe? */ 281 } 282 283 void 284 jensenio_isa_attach_hook(struct device *parent, struct device *self, 285 struct isabus_attach_args *iba) 286 { 287 288 /* Nothing to do. */ 289 } 290