1 /* $NetBSD: gemini_obio.c,v 1.12 2021/08/07 16:18:44 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.12 2021/08/07 16:18:44 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 CFARGS(.search = obio_search, 209 .iattr = "obio")); 210 211 #if NPCI > 0 212 /* 213 * attach the PCI bus 214 */ 215 pba.pba_memt = sc->sc_iot; 216 pba.pba_iot = sc->sc_iot; 217 pba.pba_dmat = sc->sc_dmat; 218 pba.pba_dmat64 = NULL; 219 pba.pba_pc = &sc->sc_pci_chipset; 220 pba.pba_bus = 0; 221 pba.pba_bridgetag = NULL; 222 pba.pba_intrswiz = 0; 223 pba.pba_intrtag = 0; 224 pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY | 225 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; 226 227 config_found(sc->sc_dev, &pba, pcibusprint, 228 CFARGS(.iattr = "pcibus")); 229 #endif /* NPCI */ 230 231 } 232 233 static int 234 obio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 235 { 236 struct obio_softc * const sc = device_private(parent); 237 struct obio_attach_args oa; 238 239 /* Set up the attach args. */ 240 if (cf->cf_loc[OBIOCF_NOBYTEACC] == 1) { 241 #if 0 242 if (cf->cf_loc[OBIOCF_MULT] == 1) 243 oa.obio_iot = &nobyteacc_bs_tag; 244 else 245 #endif 246 panic("nobyteacc specified for device with " 247 "non-byte multiplier\n"); 248 } else { 249 switch (cf->cf_loc[OBIOCF_MULT]) { 250 case 1: 251 oa.obio_iot = &gemini_bs_tag; 252 break; 253 #if 0 254 case 2: 255 oa.obio_iot = &gemini_a2x_bs_tag; 256 break; 257 #endif 258 case 4: 259 oa.obio_iot = &gemini_a4x_bs_tag; 260 break; 261 default: 262 panic("Unsupported obio bus multiplier."); 263 break; 264 } 265 } 266 267 oa.obio_dmat = sc->sc_dmat; 268 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR]; 269 oa.obio_size = cf->cf_loc[OBIOCF_SIZE]; 270 oa.obio_intr = cf->cf_loc[OBIOCF_INTR]; 271 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE]; 272 273 if (config_probe(parent, cf, &oa)) { 274 config_attach(parent, cf, &oa, obio_print, CFARGS_NONE); 275 return 0; /* love it */ 276 } 277 278 return UNCONF; /* NG */ 279 } 280 281 static int 282 obio_find(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 283 { 284 struct obio_attach_args * const oa = aux; 285 286 if (oa->obio_addr != OBIOCF_ADDR_DEFAULT 287 && oa->obio_addr != cf->cf_loc[OBIOCF_ADDR]) 288 return 0; 289 if (oa->obio_size != OBIOCF_SIZE_DEFAULT 290 && oa->obio_size != cf->cf_loc[OBIOCF_SIZE]) 291 return 0; 292 if (oa->obio_intr != OBIOCF_INTR_DEFAULT 293 && oa->obio_intr != cf->cf_loc[OBIOCF_INTR]) 294 return 0; 295 if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT 296 && oa->obio_intrbase != cf->cf_loc[OBIOCF_INTRBASE]) 297 return 0; 298 299 /* Set up the attach args. */ 300 if (cf->cf_loc[OBIOCF_NOBYTEACC] == 1) { 301 #if 0 302 if (cf->cf_loc[OBIOCF_MULT] == 1) 303 oa->obio_iot = &nobyteacc_bs_tag; 304 else 305 #endif 306 panic("nobyteacc specified for device with " 307 "non-byte multiplier\n"); 308 } else { 309 switch (cf->cf_loc[OBIOCF_MULT]) { 310 case 1: 311 oa->obio_iot = &gemini_bs_tag; 312 break; 313 #if 0 314 case 2: 315 oa->obio_iot = &gemini_a2x_bs_tag; 316 break; 317 #endif 318 case 4: 319 oa->obio_iot = &gemini_a4x_bs_tag; 320 break; 321 default: 322 panic("Unsupported obio bus multiplier."); 323 break; 324 } 325 } 326 oa->obio_addr = cf->cf_loc[OBIOCF_ADDR]; 327 oa->obio_size = cf->cf_loc[OBIOCF_SIZE]; 328 oa->obio_intr = cf->cf_loc[OBIOCF_INTR]; 329 oa->obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE]; 330 331 return config_match(parent, cf, oa); 332 } 333 334 #if NGEMINIICU == 0 335 #error no geminiicu present in config file 336 #endif 337 338 static const struct { 339 const char *name; 340 bus_addr_t addr; 341 bool required; 342 } critical_devs[] = { 343 #if defined(GEMINI_MASTER) || defined(GEMINI_SINGLE) 344 { .name = "geminiicu0", .addr = 0x48000000, .required = true }, 345 { .name = "geminiwdt0", .addr = 0x41000000, .required = true }, 346 { .name = "geminitmr0", .addr = 0x43000000, .required = true }, 347 { .name = "geminitmr2", .addr = 0x43000000, .required = true }, 348 { .name = "com0", .addr = 0x42000000, .required = true }, 349 #elif defined(GEMINI_SLAVE) 350 { .name = "geminiicu1", .addr = 0x49000000, .required = true }, 351 { .name = "geminitmr1", .addr = 0x43000000, .required = true }, 352 { .name = "geminitmr2", .addr = 0x43000000, .required = true }, 353 { .name = "geminilpchc0", .addr = 0x47000000, .required = true }, 354 #endif 355 }; 356 357 static void 358 obio_attach_critical(struct obio_softc *sc) 359 { 360 struct obio_attach_args oa; 361 cfdata_t cf; 362 size_t i; 363 364 for (i = 0; i < __arraycount(critical_devs); i++) { 365 oa.obio_iot = sc->sc_iot; 366 oa.obio_dmat = sc->sc_dmat; 367 368 oa.obio_addr = critical_devs[i].addr; 369 oa.obio_size = OBIOCF_SIZE_DEFAULT; 370 oa.obio_intr = OBIOCF_INTR_DEFAULT; 371 oa.obio_intrbase = OBIOCF_INTRBASE_DEFAULT; 372 373 #if 0 374 if (oa.obio_addr != OBIOCF_ADDR_DEFAULT 375 && (oa.obio_addr < sc->sc_base 376 || oa.obio_addr >= sc->sc_base + sc->sc_size)) 377 continue; 378 #endif 379 380 cf = config_search(sc->sc_dev, &oa, 381 CFARGS(.submatch = obio_find, 382 .iattr = "obio")); 383 if (cf == NULL && critical_devs[i].required) 384 panic("obio_attach_critical: failed to find %s!", 385 critical_devs[i].name); 386 387 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR]; 388 oa.obio_size = cf->cf_loc[OBIOCF_SIZE]; 389 oa.obio_intr = cf->cf_loc[OBIOCF_INTR]; 390 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE]; 391 config_attach(sc->sc_dev, cf, &oa, obio_print, CFARGS_NONE); 392 } 393 } 394 395 static int 396 obio_print(void *aux, const char *name) 397 { 398 struct obio_attach_args *oa = (struct obio_attach_args*)aux; 399 400 if (oa->obio_addr != OBIOCF_ADDR_DEFAULT) { 401 aprint_normal(" addr 0x%08lx", oa->obio_addr); 402 if (oa->obio_size != OBIOCF_SIZE_DEFAULT) 403 aprint_normal("-0x%08lx", 404 oa->obio_addr + oa->obio_size-1); 405 } 406 if (oa->obio_intr != OBIOCF_INTR_DEFAULT) 407 aprint_normal(" intr %d", oa->obio_intr); 408 if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT) 409 aprint_normal(" intrbase %d", oa->obio_intrbase); 410 411 return UNCONF; 412 } 413