1 /* $NetBSD: gemini_obio.c,v 1.11 2021/04/24 23:36:27 thorpej Exp $ */ 2 3 /* adapted from: 4 * NetBSD: omap2_obio.c,v 1.5 2008/10/21 18:50:25 matt Exp 5 */ 6 7 /* 8 * Autoconfiguration support for the Gemini "On Board" I/O. 9 * 10 * Based on arm/omap/omap2_obio.c which in turn was derived 11 * Based on arm/omap/omap_emifs.c which in turn was derived 12 * Based on arm/xscale/pxa2x0.c which in turn was derived 13 * from arm/sa11x0/sa11x0.c 14 * 15 * Copyright (c) 2002, 2005 Genetec Corporation. All rights reserved. 16 * Written by Hiroyuki Bessho for Genetec Corporation. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 1. Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in the 25 * documentation and/or other materials provided with the distribution. 26 * 3. All advertising materials mentioning features or use of this software 27 * must display the following acknowledgement: 28 * This product includes software developed for the NetBSD Project by 29 * Genetec Corporation. 30 * 4. The name of Genetec Corporation may not be used to endorse or 31 * promote products derived from this software without specific prior 32 * written permission. 33 * 34 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 36 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 37 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 38 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 39 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 40 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 43 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 44 * POSSIBILITY OF SUCH DAMAGE. 45 * 46 * Copyright (c) 1997,1998, 2001, The NetBSD Foundation, Inc. 47 * All rights reserved. 48 * 49 * This code is derived from software contributed to The NetBSD Foundation 50 * by IWAMOTO Toshihiro, Ichiro FUKUHARA and Paul Kranenburg. 51 * 52 * Redistribution and use in source and binary forms, with or without 53 * modification, are permitted provided that the following conditions 54 * are met: 55 * 1. Redistributions of source code must retain the above copyright 56 * notice, this list of conditions and the following disclaimer. 57 * 2. Redistributions in binary form must reproduce the above copyright 58 * notice, this list of conditions and the following disclaimer in the 59 * documentation and/or other materials provided with the distribution. 60 * 61 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 62 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 63 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 64 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 65 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 66 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 67 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 68 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 69 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 70 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 71 * POSSIBILITY OF SUCH DAMAGE. 72 * 73 * Copyright (c) 1999 74 * Shin Takemura and PocketBSD Project. All rights reserved. 75 * 76 * Redistribution and use in source and binary forms, with or without 77 * modification, are permitted provided that the following conditions 78 * are met: 79 * 1. Redistributions of source code must retain the above copyright 80 * notice, this list of conditions and the following disclaimer. 81 * 2. Redistributions in binary form must reproduce the above copyright 82 * notice, this list of conditions and the following disclaimer in the 83 * documentation and/or other materials provided with the distribution. 84 * 3. All advertising materials mentioning features or use of this software 85 * must display the following acknowledgement: 86 * This product includes software developed by the PocketBSD project 87 * and its contributors. 88 * 4. Neither the name of the project nor the names of its contributors 89 * may be used to endorse or promote products derived from this software 90 * without specific prior written permission. 91 * 92 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 93 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 95 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 96 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 97 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 98 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 100 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 101 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 102 * SUCH DAMAGE. 103 */ 104 105 #include "opt_gemini.h" 106 #include <sys/cdefs.h> 107 __KERNEL_RCSID(0, "$NetBSD: gemini_obio.c,v 1.11 2021/04/24 23:36:27 thorpej Exp $"); 108 109 #include "locators.h" 110 #include "obio.h" 111 #include "geminiicu.h" 112 #include "pci.h" 113 114 #include <sys/param.h> 115 #include <sys/systm.h> 116 #include <sys/device.h> 117 #include <sys/kernel.h> 118 #include <sys/reboot.h> 119 120 #include <machine/cpu.h> 121 #include <sys/bus.h> 122 123 #include <arm/cpufunc.h> 124 #include <arm/mainbus/mainbus.h> 125 #include <arm/gemini/gemini_var.h> 126 #include <arm/gemini/gemini_reg.h> 127 128 #include <arm/gemini/gemini_obiovar.h> 129 130 typedef struct { 131 boolean_t cs_valid; 132 ulong cs_addr; 133 ulong cs_size; 134 } obio_csconfig_t; 135 136 /* prototypes */ 137 static int obio_match(device_t, cfdata_t, void *); 138 static void obio_attach(device_t, device_t, void *); 139 static int obio_search(device_t, cfdata_t, const int *, void *); 140 static int obio_find(device_t, cfdata_t, const int *, void *); 141 static int obio_print(void *, const char *); 142 static void obio_attach_critical(struct obio_softc *); 143 144 /* attach structures */ 145 CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc), 146 obio_match, obio_attach, NULL, NULL); 147 148 149 static int 150 obio_match(device_t parent, cfdata_t match, void *aux) 151 { 152 return 1; 153 } 154 155 static void 156 obio_attach(device_t parent, device_t self, void *aux) 157 { 158 struct obio_softc *sc = device_private(self); 159 struct mainbus_attach_args *mb = (struct mainbus_attach_args *)aux; 160 #if NPCI > 0 161 struct pcibus_attach_args pba; 162 #endif 163 164 sc->sc_dev = self; 165 166 sc->sc_iot = &gemini_bs_tag; 167 168 aprint_normal(": On-Board IO\n"); 169 170 #if (GEMINI_BUSBASE != 0) 171 sc->sc_dmarange.dr_sysbase = 0; 172 sc->sc_dmarange.dr_busbase = (GEMINI_BUSBASE * 1024 * 1024); 173 sc->sc_dmarange.dr_len = MEMSIZE * 1024 * 1024; 174 gemini_bus_dma_tag._ranges = &sc->sc_dmarange; 175 gemini_bus_dma_tag._nranges = 1; 176 #endif 177 178 sc->sc_ioh = 0; 179 sc->sc_dmat = &gemini_bus_dma_tag; 180 sc->sc_base = mb->mb_iobase; 181 sc->sc_size = mb->mb_iosize; 182 183 /* 184 * Attach critical devices first. 185 */ 186 obio_attach_critical(sc); 187 188 #if NPCI > 0 189 /* 190 * map PCI controller registers 191 */ 192 if (bus_space_map(sc->sc_iot, GEMINI_PCICFG_BASE, 193 GEMINI_PCI_CFG_DATA+4, 0, &sc->sc_pcicfg_ioh)) { 194 aprint_error("cannot map PCI controller at %#x\n", 195 GEMINI_PCICFG_BASE); 196 return; 197 } 198 /* 199 * initialize the PCI chipset tag 200 */ 201 gemini_pci_init(&sc->sc_pci_chipset, sc); 202 #endif /* NPCI */ 203 204 /* 205 * attach the rest of our devices 206 */ 207 config_search(self, NULL, 208 CFARG_SEARCH, obio_search, 209 CFARG_IATTR, "obio", 210 CFARG_EOL); 211 212 #if NPCI > 0 213 /* 214 * attach the PCI bus 215 */ 216 pba.pba_memt = sc->sc_iot; 217 pba.pba_iot = sc->sc_iot; 218 pba.pba_dmat = sc->sc_dmat; 219 pba.pba_dmat64 = NULL; 220 pba.pba_pc = &sc->sc_pci_chipset; 221 pba.pba_bus = 0; 222 pba.pba_bridgetag = NULL; 223 pba.pba_intrswiz = 0; 224 pba.pba_intrtag = 0; 225 pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | 226 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; 227 228 config_found(sc->sc_dev, &pba, pcibusprint, 229 CFARG_IATTR, "pcibus", 230 CFARG_EOL); 231 #endif /* NPCI */ 232 233 } 234 235 static int 236 obio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 237 { 238 struct obio_softc * const sc = device_private(parent); 239 struct obio_attach_args oa; 240 241 /* Set up the attach args. */ 242 if (cf->cf_loc[OBIOCF_NOBYTEACC] == 1) { 243 #if 0 244 if (cf->cf_loc[OBIOCF_MULT] == 1) 245 oa.obio_iot = &nobyteacc_bs_tag; 246 else 247 #endif 248 panic("nobyteacc specified for device with " 249 "non-byte multiplier\n"); 250 } else { 251 switch (cf->cf_loc[OBIOCF_MULT]) { 252 case 1: 253 oa.obio_iot = &gemini_bs_tag; 254 break; 255 #if 0 256 case 2: 257 oa.obio_iot = &gemini_a2x_bs_tag; 258 break; 259 #endif 260 case 4: 261 oa.obio_iot = &gemini_a4x_bs_tag; 262 break; 263 default: 264 panic("Unsupported obio bus multiplier."); 265 break; 266 } 267 } 268 269 oa.obio_dmat = sc->sc_dmat; 270 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR]; 271 oa.obio_size = cf->cf_loc[OBIOCF_SIZE]; 272 oa.obio_intr = cf->cf_loc[OBIOCF_INTR]; 273 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE]; 274 275 if (config_probe(parent, cf, &oa)) { 276 config_attach(parent, cf, &oa, obio_print, CFARG_EOL); 277 return 0; /* love it */ 278 } 279 280 return UNCONF; /* NG */ 281 } 282 283 static int 284 obio_find(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 285 { 286 struct obio_attach_args * const oa = aux; 287 288 if (oa->obio_addr != OBIOCF_ADDR_DEFAULT 289 && oa->obio_addr != cf->cf_loc[OBIOCF_ADDR]) 290 return 0; 291 if (oa->obio_size != OBIOCF_SIZE_DEFAULT 292 && oa->obio_size != cf->cf_loc[OBIOCF_SIZE]) 293 return 0; 294 if (oa->obio_intr != OBIOCF_INTR_DEFAULT 295 && oa->obio_intr != cf->cf_loc[OBIOCF_INTR]) 296 return 0; 297 if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT 298 && oa->obio_intrbase != cf->cf_loc[OBIOCF_INTRBASE]) 299 return 0; 300 301 /* Set up the attach args. */ 302 if (cf->cf_loc[OBIOCF_NOBYTEACC] == 1) { 303 #if 0 304 if (cf->cf_loc[OBIOCF_MULT] == 1) 305 oa->obio_iot = &nobyteacc_bs_tag; 306 else 307 #endif 308 panic("nobyteacc specified for device with " 309 "non-byte multiplier\n"); 310 } else { 311 switch (cf->cf_loc[OBIOCF_MULT]) { 312 case 1: 313 oa->obio_iot = &gemini_bs_tag; 314 break; 315 #if 0 316 case 2: 317 oa->obio_iot = &gemini_a2x_bs_tag; 318 break; 319 #endif 320 case 4: 321 oa->obio_iot = &gemini_a4x_bs_tag; 322 break; 323 default: 324 panic("Unsupported obio bus multiplier."); 325 break; 326 } 327 } 328 oa->obio_addr = cf->cf_loc[OBIOCF_ADDR]; 329 oa->obio_size = cf->cf_loc[OBIOCF_SIZE]; 330 oa->obio_intr = cf->cf_loc[OBIOCF_INTR]; 331 oa->obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE]; 332 333 return config_match(parent, cf, oa); 334 } 335 336 #if NGEMINIICU == 0 337 #error no geminiicu present in config file 338 #endif 339 340 static const struct { 341 const char *name; 342 bus_addr_t addr; 343 bool required; 344 } critical_devs[] = { 345 #if defined(GEMINI_MASTER) || defined(GEMINI_SINGLE) 346 { .name = "geminiicu0", .addr = 0x48000000, .required = true }, 347 { .name = "geminiwdt0", .addr = 0x41000000, .required = true }, 348 { .name = "geminitmr0", .addr = 0x43000000, .required = true }, 349 { .name = "geminitmr2", .addr = 0x43000000, .required = true }, 350 { .name = "com0", .addr = 0x42000000, .required = true }, 351 #elif defined(GEMINI_SLAVE) 352 { .name = "geminiicu1", .addr = 0x49000000, .required = true }, 353 { .name = "geminitmr1", .addr = 0x43000000, .required = true }, 354 { .name = "geminitmr2", .addr = 0x43000000, .required = true }, 355 { .name = "geminilpchc0", .addr = 0x47000000, .required = true }, 356 #endif 357 }; 358 359 static void 360 obio_attach_critical(struct obio_softc *sc) 361 { 362 struct obio_attach_args oa; 363 cfdata_t cf; 364 size_t i; 365 366 for (i = 0; i < __arraycount(critical_devs); i++) { 367 oa.obio_iot = sc->sc_iot; 368 oa.obio_dmat = sc->sc_dmat; 369 370 oa.obio_addr = critical_devs[i].addr; 371 oa.obio_size = OBIOCF_SIZE_DEFAULT; 372 oa.obio_intr = OBIOCF_INTR_DEFAULT; 373 oa.obio_intrbase = OBIOCF_INTRBASE_DEFAULT; 374 375 #if 0 376 if (oa.obio_addr != OBIOCF_ADDR_DEFAULT 377 && (oa.obio_addr < sc->sc_base 378 || oa.obio_addr >= sc->sc_base + sc->sc_size)) 379 continue; 380 #endif 381 382 cf = config_search(sc->sc_dev, &oa, 383 CFARG_SUBMATCH, obio_find, 384 CFARG_IATTR, "obio", 385 CFARG_EOL); 386 if (cf == NULL && critical_devs[i].required) 387 panic("obio_attach_critical: failed to find %s!", 388 critical_devs[i].name); 389 390 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR]; 391 oa.obio_size = cf->cf_loc[OBIOCF_SIZE]; 392 oa.obio_intr = cf->cf_loc[OBIOCF_INTR]; 393 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE]; 394 config_attach(sc->sc_dev, cf, &oa, obio_print, CFARG_EOL); 395 } 396 } 397 398 static int 399 obio_print(void *aux, const char *name) 400 { 401 struct obio_attach_args *oa = (struct obio_attach_args*)aux; 402 403 if (oa->obio_addr != OBIOCF_ADDR_DEFAULT) { 404 aprint_normal(" addr 0x%08lx", oa->obio_addr); 405 if (oa->obio_size != OBIOCF_SIZE_DEFAULT) 406 aprint_normal("-0x%08lx", 407 oa->obio_addr + oa->obio_size-1); 408 } 409 if (oa->obio_intr != OBIOCF_INTR_DEFAULT) 410 aprint_normal(" intr %d", oa->obio_intr); 411 if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT) 412 aprint_normal(" intrbase %d", oa->obio_intrbase); 413 414 return UNCONF; 415 } 416