1 /*- 2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 3 * All rights reserved. 4 * 5 * Developed by Semihalf. 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. Neither the name of MARVELL nor the names of contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* 33 * Marvell integrated PCI/PCI-Express controller driver. 34 */ 35 36 #include <sys/cdefs.h> 37 __FBSDID("$FreeBSD$"); 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/kernel.h> 42 #include <sys/lock.h> 43 #include <sys/malloc.h> 44 #include <sys/module.h> 45 #include <sys/mutex.h> 46 #include <sys/queue.h> 47 #include <sys/bus.h> 48 #include <sys/rman.h> 49 #include <sys/endian.h> 50 51 #include <vm/vm.h> 52 #include <vm/pmap.h> 53 54 #include <dev/pci/pcivar.h> 55 #include <dev/pci/pcireg.h> 56 #include <dev/pci/pcib_private.h> 57 58 #include "pcib_if.h" 59 60 #include <machine/resource.h> 61 #include <machine/bus.h> 62 63 #include <arm/mv/mvreg.h> 64 #include <arm/mv/mvvar.h> 65 66 #define PCI_CFG_ENA (1 << 31) 67 #define PCI_CFG_BUS(bus) (((bus) & 0xff) << 16) 68 #define PCI_CFG_DEV(dev) (((dev) & 0x1f) << 11) 69 #define PCI_CFG_FUN(fun) (((fun) & 0x7) << 8) 70 #define PCI_CFG_PCIE_REG(reg) ((reg) & 0xfc) 71 72 #define PCI_REG_CFG_ADDR 0x0C78 73 #define PCI_REG_CFG_DATA 0x0C7C 74 #define PCI_REG_P2P_CONF 0x1D14 75 76 #define PCIE_REG_CFG_ADDR 0x18F8 77 #define PCIE_REG_CFG_DATA 0x18FC 78 #define PCIE_REG_CONTROL 0x1A00 79 #define PCIE_CTRL_LINK1X 0x00000001 80 #define PCIE_REG_STATUS 0x1A04 81 #define PCIE_REG_IRQ_MASK 0x1910 82 83 #define STATUS_LINK_DOWN 1 84 #define STATUS_BUS_OFFS 8 85 #define STATUS_BUS_MASK (0xFF << STATUS_BUS_OFFS) 86 #define STATUS_DEV_OFFS 16 87 #define STATUS_DEV_MASK (0x1F << STATUS_DEV_OFFS) 88 89 #define P2P_CONF_BUS_OFFS 16 90 #define P2P_CONF_BUS_MASK (0xFF << P2P_CONF_BUS_OFFS) 91 #define P2P_CONF_DEV_OFFS 24 92 #define P2P_CONF_DEV_MASK (0x1F << P2P_CONF_DEV_OFFS) 93 94 #define PCI_VENDORID_MRVL 0x11AB 95 96 struct pcib_mbus_softc { 97 device_t sc_dev; 98 99 struct rman sc_iomem_rman; 100 bus_addr_t sc_iomem_base; 101 bus_addr_t sc_iomem_size; 102 bus_addr_t sc_iomem_alloc; /* Next allocation. */ 103 104 struct rman sc_ioport_rman; 105 bus_addr_t sc_ioport_base; 106 bus_addr_t sc_ioport_size; 107 bus_addr_t sc_ioport_alloc; /* Next allocation. */ 108 109 struct resource *sc_res; 110 bus_space_handle_t sc_bsh; 111 bus_space_tag_t sc_bst; 112 int sc_rid; 113 114 int sc_busnr; /* Host bridge bus number */ 115 int sc_devnr; /* Host bridge device number */ 116 117 const struct obio_pci *sc_info; 118 }; 119 120 static void pcib_mbus_identify(driver_t *driver, device_t parent); 121 static int pcib_mbus_probe(device_t); 122 static int pcib_mbus_attach(device_t); 123 124 static struct resource *pcib_mbus_alloc_resource(device_t, device_t, int, int *, 125 u_long, u_long, u_long, u_int); 126 static int pcib_mbus_release_resource(device_t, device_t, int, int, 127 struct resource *); 128 static int pcib_mbus_read_ivar(device_t, device_t, int, uintptr_t *); 129 static int pcib_mbus_write_ivar(device_t, device_t, int, uintptr_t); 130 131 static int pcib_mbus_maxslots(device_t); 132 static uint32_t pcib_mbus_read_config(device_t, u_int, u_int, u_int, u_int, 133 int); 134 static void pcib_mbus_write_config(device_t, u_int, u_int, u_int, u_int, 135 uint32_t, int); 136 static int pcib_mbus_init(struct pcib_mbus_softc *sc, int bus, int maxslot); 137 static int pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, 138 int func, int barno); 139 static void pcib_mbus_init_bridge(struct pcib_mbus_softc *sc, int bus, int slot, 140 int func); 141 static int pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, 142 int slot, int func, int hdrtype); 143 144 /* 145 * Bus interface definitions. 146 */ 147 static device_method_t pcib_mbus_methods[] = { 148 /* Device interface */ 149 DEVMETHOD(device_identify, pcib_mbus_identify), 150 DEVMETHOD(device_probe, pcib_mbus_probe), 151 DEVMETHOD(device_attach, pcib_mbus_attach), 152 153 /* Bus interface */ 154 DEVMETHOD(bus_print_child, bus_generic_print_child), 155 DEVMETHOD(bus_read_ivar, pcib_mbus_read_ivar), 156 DEVMETHOD(bus_write_ivar, pcib_mbus_write_ivar), 157 DEVMETHOD(bus_alloc_resource, pcib_mbus_alloc_resource), 158 DEVMETHOD(bus_release_resource, pcib_mbus_release_resource), 159 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 160 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 161 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 162 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 163 164 /* pcib interface */ 165 DEVMETHOD(pcib_maxslots, pcib_mbus_maxslots), 166 DEVMETHOD(pcib_read_config, pcib_mbus_read_config), 167 DEVMETHOD(pcib_write_config, pcib_mbus_write_config), 168 DEVMETHOD(pcib_route_interrupt, pcib_route_interrupt), 169 170 { 0, 0 } 171 }; 172 173 static driver_t pcib_mbus_driver = { 174 "pcib", 175 pcib_mbus_methods, 176 sizeof(struct pcib_mbus_softc), 177 }; 178 179 devclass_t pcib_devclass; 180 181 DRIVER_MODULE(pcib, mbus, pcib_mbus_driver, pcib_devclass, 0, 0); 182 183 static struct mtx pcicfg_mtx; 184 185 static inline void 186 pcib_write_irq_mask(struct pcib_mbus_softc *sc, uint32_t mask) 187 { 188 189 if (!sc->sc_info->op_type != MV_TYPE_PCI) 190 return; 191 192 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 193 PCIE_REG_IRQ_MASK, mask); 194 } 195 196 static void 197 pcib_mbus_hw_cfginit(void) 198 { 199 static int opened = 0; 200 201 if (opened) 202 return; 203 204 mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN); 205 opened = 1; 206 } 207 208 static uint32_t 209 pcib_mbus_hw_cfgread(struct pcib_mbus_softc *sc, u_int bus, u_int slot, 210 u_int func, u_int reg, int bytes) 211 { 212 uint32_t addr, data, ca, cd; 213 214 ca = (sc->sc_info->op_type != MV_TYPE_PCI) ? 215 PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR; 216 cd = (sc->sc_info->op_type != MV_TYPE_PCI) ? 217 PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA; 218 addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | 219 PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg); 220 221 mtx_lock_spin(&pcicfg_mtx); 222 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr); 223 224 data = ~0; 225 switch (bytes) { 226 case 1: 227 data = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 228 cd + (reg & 3)); 229 break; 230 case 2: 231 data = le16toh(bus_space_read_2(sc->sc_bst, sc->sc_bsh, 232 cd + (reg & 2))); 233 break; 234 case 4: 235 data = le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 236 cd)); 237 break; 238 } 239 mtx_unlock_spin(&pcicfg_mtx); 240 return (data); 241 } 242 243 static void 244 pcib_mbus_hw_cfgwrite(struct pcib_mbus_softc *sc, u_int bus, u_int slot, 245 u_int func, u_int reg, uint32_t data, int bytes) 246 { 247 uint32_t addr, ca, cd; 248 249 ca = (sc->sc_info->op_type != MV_TYPE_PCI) ? 250 PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR; 251 cd = (sc->sc_info->op_type != MV_TYPE_PCI) ? 252 PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA; 253 addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | 254 PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg); 255 256 mtx_lock_spin(&pcicfg_mtx); 257 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr); 258 259 switch (bytes) { 260 case 1: 261 bus_space_write_1(sc->sc_bst, sc->sc_bsh, 262 cd + (reg & 3), data); 263 break; 264 case 2: 265 bus_space_write_2(sc->sc_bst, sc->sc_bsh, 266 cd + (reg & 2), htole16(data)); 267 break; 268 case 4: 269 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 270 cd, htole32(data)); 271 break; 272 } 273 mtx_unlock_spin(&pcicfg_mtx); 274 } 275 276 static int 277 pcib_mbus_maxslots(device_t dev) 278 { 279 struct pcib_mbus_softc *sc = device_get_softc(dev); 280 281 return ((sc->sc_info->op_type != MV_TYPE_PCI) ? 1 : PCI_SLOTMAX); 282 } 283 284 static uint32_t 285 pcib_mbus_read_config(device_t dev, u_int bus, u_int slot, u_int func, 286 u_int reg, int bytes) 287 { 288 struct pcib_mbus_softc *sc = device_get_softc(dev); 289 290 /* Skip self */ 291 if (bus == sc->sc_busnr && slot == sc->sc_devnr) 292 return (~0U); 293 294 return (pcib_mbus_hw_cfgread(sc, bus, slot, func, reg, bytes)); 295 } 296 297 static void 298 pcib_mbus_write_config(device_t dev, u_int bus, u_int slot, u_int func, 299 u_int reg, uint32_t val, int bytes) 300 { 301 struct pcib_mbus_softc *sc = device_get_softc(dev); 302 303 /* Skip self */ 304 if (bus == sc->sc_busnr && slot == sc->sc_devnr) 305 return; 306 307 pcib_mbus_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes); 308 } 309 310 static void 311 pcib_mbus_add_child(driver_t *driver, device_t parent, struct pcib_mbus_softc *sc) 312 { 313 device_t child; 314 int error; 315 316 /* Configure CPU decoding windows */ 317 error = decode_win_cpu_set(sc->sc_info->op_io_win_target, 318 sc->sc_info->op_io_win_attr, sc->sc_info->op_io_base, 319 sc->sc_info->op_io_size, -1); 320 if (error < 0) { 321 device_printf(parent, "Could not set up CPU decode " 322 "window for PCI IO\n"); 323 return; 324 } 325 error = decode_win_cpu_set(sc->sc_info->op_mem_win_target, 326 sc->sc_info->op_mem_win_attr, sc->sc_info->op_mem_base, 327 sc->sc_info->op_mem_size, -1); 328 if (error < 0) { 329 device_printf(parent, "Could not set up CPU decode " 330 "windows for PCI MEM\n"); 331 return; 332 } 333 334 /* Create driver instance */ 335 child = BUS_ADD_CHILD(parent, 0, driver->name, -1); 336 bus_set_resource(child, SYS_RES_MEMORY, 0, 337 sc->sc_info->op_base, sc->sc_info->op_size); 338 device_set_softc(child, sc); 339 } 340 341 static void 342 pcib_mbus_identify(driver_t *driver, device_t parent) 343 { 344 const struct obio_pci *info = mv_pci_info; 345 struct pcib_mbus_softc *sc; 346 uint32_t control; 347 348 while (info->op_base) { 349 sc = malloc(driver->size, M_DEVBUF, M_NOWAIT | M_ZERO); 350 if (sc == NULL) { 351 device_printf(parent, "Could not allocate pcib " 352 "memory\n"); 353 break; 354 } 355 sc->sc_info = info++; 356 357 /* 358 * PCI bridge objects are instantiated immediately. PCI-Express 359 * bridges require more complicated handling depending on 360 * platform configuration. 361 */ 362 if (sc->sc_info->op_type == MV_TYPE_PCI) { 363 pcib_mbus_add_child(driver, parent, sc); 364 continue; 365 } 366 367 /* 368 * Read link configuration 369 */ 370 sc->sc_rid = 0; 371 sc->sc_res = BUS_ALLOC_RESOURCE(parent, parent, SYS_RES_MEMORY, 372 &sc->sc_rid, sc->sc_info->op_base, sc->sc_info->op_base + 373 sc->sc_info->op_size - 1, sc->sc_info->op_size, 374 RF_ACTIVE); 375 if (sc->sc_res == NULL) { 376 device_printf(parent, "Could not map pcib memory\n"); 377 break; 378 } 379 380 sc->sc_bst = rman_get_bustag(sc->sc_res); 381 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 382 383 control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 384 PCIE_REG_CONTROL); 385 386 BUS_RELEASE_RESOURCE(parent, parent, SYS_RES_MEMORY, sc->sc_rid, 387 sc->sc_res); 388 389 /* 390 * If this PCI-E port (controller) is configured (by the 391 * underlying firmware) with lane width other than 1x, there 392 * are auxiliary resources defined for aggregating more width 393 * on our lane. Skip all such entries as they are not 394 * standalone ports and must not have a device object 395 * instantiated. 396 */ 397 if ((control & PCIE_CTRL_LINK1X) == 0) 398 while (info->op_base && 399 info->op_type == MV_TYPE_PCIE_AGGR_LANE) 400 info++; 401 402 pcib_mbus_add_child(driver, parent, sc); 403 } 404 } 405 406 static int 407 pcib_mbus_probe(device_t self) 408 { 409 char buf[128]; 410 struct pcib_mbus_softc *sc; 411 const char *id, *type; 412 uint32_t val; 413 int rv = ENOENT, bus, dev; 414 415 sc = device_get_softc(self); 416 417 sc->sc_rid = 0; 418 sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid, 419 RF_ACTIVE); 420 if (sc->sc_res == NULL) { 421 device_printf(self, "Could not map memory\n"); 422 return (ENXIO); 423 } 424 425 sc->sc_bst = rman_get_bustag(sc->sc_res); 426 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 427 428 pcib_mbus_hw_cfginit(); 429 430 /* Retrieve configuration of the bridge */ 431 if (sc->sc_info->op_type == MV_TYPE_PCI) { 432 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 433 PCI_REG_P2P_CONF); 434 bus = sc->sc_busnr = (val & P2P_CONF_BUS_MASK) >> 435 P2P_CONF_BUS_OFFS; 436 dev = sc->sc_devnr = (val & P2P_CONF_DEV_MASK) >> 437 P2P_CONF_DEV_OFFS; 438 } else { 439 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS); 440 if (val & STATUS_LINK_DOWN) 441 goto out; 442 bus = sc->sc_busnr = (val & STATUS_BUS_MASK) >> STATUS_BUS_OFFS; 443 dev = sc->sc_devnr = (val & STATUS_DEV_MASK) >> STATUS_DEV_OFFS; 444 } 445 446 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_VENDOR, 2); 447 if (val != PCI_VENDORID_MRVL) 448 goto out; 449 450 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_DEVICE, 2); 451 switch (val) { 452 case 0x5281: 453 id = "88F5281"; 454 break; 455 case 0x5182: 456 id = "88F5182"; 457 break; 458 case 0x6281: 459 id = "88F6281"; 460 break; 461 case 0x6381: 462 id = "MV78100 Z0"; 463 break; 464 case 0x7810: 465 id = "MV78100"; 466 break; 467 case 0x7820: 468 /* 469 * According to documentation ID 0x7820 is assigned to MV78200. 470 * However some MV78100 chips also use it. 471 */ 472 id = "MV78100/MV78200"; 473 break; 474 default: 475 device_printf(self, "unknown Marvell PCI bridge: %x\n", val); 476 goto out; 477 } 478 479 type = "PCI"; 480 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_CAP_PTR, 1); 481 while (val != 0) { 482 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, val, 2); 483 switch (val & 0xff) { 484 case PCIY_PCIX: 485 type = "PCI-X"; 486 break; 487 case PCIY_EXPRESS: 488 type = "PCI-Express"; 489 break; 490 } 491 val = (val >> 8) & 0xff; 492 } 493 494 snprintf(buf, sizeof(buf), "Marvell %s %s host controller", id, 495 type); 496 device_set_desc_copy(self, buf); 497 rv = BUS_PROBE_DEFAULT; 498 out: 499 bus_release_resource(self, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res); 500 return (rv); 501 } 502 503 static int 504 pcib_mbus_attach(device_t self) 505 { 506 struct pcib_mbus_softc *sc; 507 uint32_t val; 508 int err; 509 510 sc = device_get_softc(self); 511 sc->sc_dev = self; 512 513 sc->sc_rid = 0; 514 sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid, 515 RF_ACTIVE); 516 if (sc->sc_res == NULL) { 517 device_printf(self, "Could not map memory\n"); 518 return (ENXIO); 519 } 520 sc->sc_bst = rman_get_bustag(sc->sc_res); 521 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 522 523 /* Enable PCI bridge */ 524 val = pcib_mbus_hw_cfgread(sc, sc->sc_busnr, sc->sc_devnr, 0, 525 PCIR_COMMAND, 2); 526 val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 527 PCIM_CMD_PORTEN; 528 pcib_mbus_hw_cfgwrite(sc, sc->sc_busnr, sc->sc_devnr, 0, 529 PCIR_COMMAND, val, 2); 530 531 sc->sc_iomem_base = sc->sc_info->op_mem_base; 532 sc->sc_iomem_size = sc->sc_info->op_mem_size; 533 sc->sc_iomem_alloc = sc->sc_info->op_mem_base; 534 535 sc->sc_ioport_base = sc->sc_info->op_io_base; 536 sc->sc_ioport_size = sc->sc_info->op_io_size; 537 sc->sc_ioport_alloc = sc->sc_info->op_io_base; 538 539 sc->sc_iomem_rman.rm_type = RMAN_ARRAY; 540 err = rman_init(&sc->sc_iomem_rman); 541 if (err) 542 return (err); 543 544 sc->sc_ioport_rman.rm_type = RMAN_ARRAY; 545 err = rman_init(&sc->sc_ioport_rman); 546 if (err) { 547 rman_fini(&sc->sc_iomem_rman); 548 return (err); 549 } 550 551 err = rman_manage_region(&sc->sc_iomem_rman, sc->sc_iomem_base, 552 sc->sc_iomem_base + sc->sc_iomem_size - 1); 553 if (err) 554 goto error; 555 556 err = rman_manage_region(&sc->sc_ioport_rman, sc->sc_ioport_base, 557 sc->sc_ioport_base + sc->sc_ioport_size - 1); 558 if (err) 559 goto error; 560 561 err = pcib_mbus_init(sc, sc->sc_busnr, pcib_mbus_maxslots(sc->sc_dev)); 562 if (err) 563 goto error; 564 565 device_add_child(self, "pci", -1); 566 return (bus_generic_attach(self)); 567 568 error: 569 rman_fini(&sc->sc_iomem_rman); 570 rman_fini(&sc->sc_ioport_rman); 571 return (err); 572 } 573 574 static int 575 pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, int func, 576 int barno) 577 { 578 bus_addr_t *allocp, limit; 579 uint32_t addr, bar, mask, size; 580 int reg, width; 581 582 reg = PCIR_BAR(barno); 583 bar = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, reg, 4); 584 if (bar == 0) 585 return (1); 586 587 /* Calculate BAR size: 64 or 32 bit (in 32-bit units) */ 588 width = ((bar & 7) == 4) ? 2 : 1; 589 590 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4); 591 size = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, reg, 4); 592 593 /* Get BAR type and size */ 594 if (bar & 1) { 595 /* I/O port */ 596 allocp = &sc->sc_ioport_alloc; 597 limit = sc->sc_ioport_base + sc->sc_ioport_size; 598 size &= ~0x3; 599 if ((size & 0xffff0000) == 0) 600 size |= 0xffff0000; 601 } else { 602 /* Memory */ 603 allocp = &sc->sc_iomem_alloc; 604 limit = sc->sc_iomem_base + sc->sc_iomem_size; 605 size &= ~0xF; 606 } 607 mask = ~size; 608 size = mask + 1; 609 610 /* Sanity check (must be a power of 2) */ 611 if (size & mask) 612 return (width); 613 614 addr = (*allocp + mask) & ~mask; 615 if ((*allocp = addr + size) > limit) 616 return (-1); 617 618 if (bootverbose) 619 printf("PCI %u:%u:%u: reg %x: size=%08x: addr=%08x\n", 620 bus, slot, func, reg, size, addr); 621 622 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); 623 if (width == 2) 624 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg + 4, 625 0, 4); 626 627 return (width); 628 } 629 630 static void 631 pcib_mbus_init_bridge(struct pcib_mbus_softc *sc, int bus, int slot, int func) 632 { 633 bus_addr_t io_base, mem_base; 634 uint32_t io_limit, mem_limit; 635 int secbus; 636 637 io_base = sc->sc_info->op_io_base; 638 io_limit = io_base + sc->sc_info->op_io_size - 1; 639 mem_base = sc->sc_info->op_mem_base; 640 mem_limit = mem_base + sc->sc_info->op_mem_size - 1; 641 642 /* Configure I/O decode registers */ 643 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEL_1, 644 io_base >> 8, 1); 645 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEH_1, 646 io_base >> 16, 2); 647 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITL_1, 648 io_limit >> 8, 1); 649 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITH_1, 650 io_limit >> 16, 2); 651 652 /* Configure memory decode registers */ 653 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMBASE_1, 654 mem_base >> 16, 2); 655 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMLIMIT_1, 656 mem_limit >> 16, 2); 657 658 /* Disable memory prefetch decode */ 659 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEL_1, 660 0x10, 2); 661 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEH_1, 662 0x0, 4); 663 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITL_1, 664 0xF, 2); 665 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITH_1, 666 0x0, 4); 667 668 secbus = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, 669 PCIR_SECBUS_1, 1); 670 671 /* Configure buses behind the bridge */ 672 pcib_mbus_init(sc, secbus, PCI_SLOTMAX); 673 } 674 675 static int 676 pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot, 677 int func, int hdrtype) 678 { 679 const struct obio_pci_irq_map *map = sc->sc_info->op_pci_irq_map; 680 int maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6; 681 int bar = 0, irq = -1; 682 int pin, i; 683 684 /* Program the base address registers */ 685 while (bar < maxbar) { 686 i = pcib_mbus_init_bar(sc, bus, slot, func, bar); 687 bar += i; 688 if (i < 0) { 689 device_printf(sc->sc_dev, 690 "PCI IO/Memory space exhausted\n"); 691 return (ENOMEM); 692 } 693 } 694 695 /* Perform interrupt routing */ 696 pin = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, 697 PCIR_INTPIN, 1); 698 699 if (map != NULL) 700 while (map->opim_irq >= 0) { 701 if ((map->opim_slot == slot || map->opim_slot < 0) && 702 (map->opim_pin == pin || map->opim_pin < 0)) 703 irq = map->opim_irq; 704 705 map++; 706 } 707 else 708 irq = sc->sc_info->op_irq; 709 710 if (irq >= 0) 711 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 712 PCIR_INTLINE, irq, 1); 713 else { 714 device_printf(sc->sc_dev, "Missing IRQ routing information " 715 "for PCI device %u:%u:%u\n", bus, slot, func); 716 return (ENXIO); 717 } 718 719 return (0); 720 } 721 722 static int 723 pcib_mbus_init(struct pcib_mbus_softc *sc, int bus, int maxslot) 724 { 725 int slot, func, maxfunc, error; 726 uint8_t hdrtype, command, class, subclass; 727 728 for (slot = 0; slot <= maxslot; slot++) { 729 maxfunc = 0; 730 for (func = 0; func <= maxfunc; func++) { 731 hdrtype = pcib_mbus_read_config(sc->sc_dev, bus, slot, 732 func, PCIR_HDRTYPE, 1); 733 734 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) 735 continue; 736 737 if (func == 0 && (hdrtype & PCIM_MFDEV)) 738 maxfunc = PCI_FUNCMAX; 739 740 command = pcib_mbus_read_config(sc->sc_dev, bus, slot, 741 func, PCIR_COMMAND, 1); 742 command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN); 743 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 744 PCIR_COMMAND, command, 1); 745 746 error = pcib_mbus_init_resources(sc, bus, slot, func, 747 hdrtype); 748 749 if (error) 750 return (error); 751 752 command |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 753 PCIM_CMD_PORTEN; 754 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 755 PCIR_COMMAND, command, 1); 756 757 /* Handle PCI-PCI bridges */ 758 class = pcib_mbus_read_config(sc->sc_dev, bus, slot, 759 func, PCIR_CLASS, 1); 760 subclass = pcib_mbus_read_config(sc->sc_dev, bus, slot, 761 func, PCIR_SUBCLASS, 1); 762 763 if (class != PCIC_BRIDGE || 764 subclass != PCIS_BRIDGE_PCI) 765 continue; 766 767 pcib_mbus_init_bridge(sc, bus, slot, func); 768 } 769 } 770 771 /* Enable all ABCD interrupts */ 772 pcib_write_irq_mask(sc, (0xF << 24)); 773 774 return (0); 775 } 776 777 static struct resource * 778 pcib_mbus_alloc_resource(device_t dev, device_t child, int type, int *rid, 779 u_long start, u_long end, u_long count, u_int flags) 780 { 781 struct pcib_mbus_softc *sc = device_get_softc(dev); 782 struct rman *rm = NULL; 783 struct resource *res; 784 785 switch (type) { 786 case SYS_RES_IOPORT: 787 rm = &sc->sc_ioport_rman; 788 break; 789 case SYS_RES_MEMORY: 790 rm = &sc->sc_iomem_rman; 791 break; 792 default: 793 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 794 type, rid, start, end, count, flags)); 795 }; 796 797 res = rman_reserve_resource(rm, start, end, count, flags, child); 798 if (res == NULL) 799 return (NULL); 800 801 rman_set_rid(res, *rid); 802 rman_set_bustag(res, obio_tag); 803 rman_set_bushandle(res, start); 804 805 if (flags & RF_ACTIVE) 806 if (bus_activate_resource(child, type, *rid, res)) { 807 rman_release_resource(res); 808 return (NULL); 809 } 810 811 return (res); 812 } 813 814 static int 815 pcib_mbus_release_resource(device_t dev, device_t child, int type, int rid, 816 struct resource *res) 817 { 818 819 if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) 820 return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 821 type, rid, res)); 822 823 return (rman_release_resource(res)); 824 } 825 826 static int 827 pcib_mbus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 828 { 829 struct pcib_mbus_softc *sc = device_get_softc(dev); 830 831 switch (which) { 832 case PCIB_IVAR_BUS: 833 *result = sc->sc_busnr; 834 return (0); 835 case PCIB_IVAR_DOMAIN: 836 *result = device_get_unit(dev); 837 return (0); 838 } 839 840 return (ENOENT); 841 } 842 843 static int 844 pcib_mbus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 845 { 846 struct pcib_mbus_softc *sc = device_get_softc(dev); 847 848 switch (which) { 849 case PCIB_IVAR_BUS: 850 sc->sc_busnr = value; 851 return (0); 852 } 853 854 return (ENOENT); 855 } 856