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"; 463 break; 464 default: 465 device_printf(self, "unknown Marvell PCI bridge: %x\n", val); 466 goto out; 467 } 468 469 type = "PCI"; 470 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_CAP_PTR, 1); 471 while (val != 0) { 472 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, val, 2); 473 switch (val & 0xff) { 474 case PCIY_PCIX: 475 type = "PCI-X"; 476 break; 477 case PCIY_EXPRESS: 478 type = "PCI-Express"; 479 break; 480 } 481 val = (val >> 8) & 0xff; 482 } 483 484 snprintf(buf, sizeof(buf), "Marvell %s %s host controller", id, 485 type); 486 device_set_desc_copy(self, buf); 487 rv = BUS_PROBE_DEFAULT; 488 out: 489 bus_release_resource(self, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res); 490 return (rv); 491 } 492 493 static int 494 pcib_mbus_attach(device_t self) 495 { 496 struct pcib_mbus_softc *sc; 497 uint32_t val; 498 int err; 499 500 sc = device_get_softc(self); 501 sc->sc_dev = self; 502 503 sc->sc_rid = 0; 504 sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid, 505 RF_ACTIVE); 506 if (sc->sc_res == NULL) { 507 device_printf(self, "Could not map memory\n"); 508 return (ENXIO); 509 } 510 sc->sc_bst = rman_get_bustag(sc->sc_res); 511 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 512 513 /* Enable PCI bridge */ 514 val = pcib_mbus_hw_cfgread(sc, sc->sc_busnr, sc->sc_devnr, 0, 515 PCIR_COMMAND, 2); 516 val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 517 PCIM_CMD_PORTEN; 518 pcib_mbus_hw_cfgwrite(sc, sc->sc_busnr, sc->sc_devnr, 0, 519 PCIR_COMMAND, val, 2); 520 521 sc->sc_iomem_base = sc->sc_info->op_mem_base; 522 sc->sc_iomem_size = sc->sc_info->op_mem_size; 523 sc->sc_iomem_alloc = sc->sc_info->op_mem_base; 524 525 sc->sc_ioport_base = sc->sc_info->op_io_base; 526 sc->sc_ioport_size = sc->sc_info->op_io_size; 527 sc->sc_ioport_alloc = sc->sc_info->op_io_base; 528 529 sc->sc_iomem_rman.rm_type = RMAN_ARRAY; 530 err = rman_init(&sc->sc_iomem_rman); 531 if (err) 532 return (err); 533 534 sc->sc_ioport_rman.rm_type = RMAN_ARRAY; 535 err = rman_init(&sc->sc_ioport_rman); 536 if (err) { 537 rman_fini(&sc->sc_iomem_rman); 538 return (err); 539 } 540 541 err = rman_manage_region(&sc->sc_iomem_rman, sc->sc_iomem_base, 542 sc->sc_iomem_base + sc->sc_iomem_size - 1); 543 if (err) 544 goto error; 545 546 err = rman_manage_region(&sc->sc_ioport_rman, sc->sc_ioport_base, 547 sc->sc_ioport_base + sc->sc_ioport_size - 1); 548 if (err) 549 goto error; 550 551 err = pcib_mbus_init(sc, sc->sc_busnr, pcib_mbus_maxslots(sc->sc_dev)); 552 if (err) 553 goto error; 554 555 device_add_child(self, "pci", -1); 556 return (bus_generic_attach(self)); 557 558 error: 559 rman_fini(&sc->sc_iomem_rman); 560 rman_fini(&sc->sc_ioport_rman); 561 return (err); 562 } 563 564 static int 565 pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, int func, 566 int barno) 567 { 568 bus_addr_t *allocp, limit; 569 uint32_t addr, bar, mask, size; 570 int reg, width; 571 572 reg = PCIR_BAR(barno); 573 bar = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, reg, 4); 574 if (bar == 0) 575 return (1); 576 577 /* Calculate BAR size: 64 or 32 bit (in 32-bit units) */ 578 width = ((bar & 7) == 4) ? 2 : 1; 579 580 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4); 581 size = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, reg, 4); 582 583 /* Get BAR type and size */ 584 if (bar & 1) { 585 /* I/O port */ 586 allocp = &sc->sc_ioport_alloc; 587 limit = sc->sc_ioport_base + sc->sc_ioport_size; 588 size &= ~0x3; 589 if ((size & 0xffff0000) == 0) 590 size |= 0xffff0000; 591 } else { 592 /* Memory */ 593 allocp = &sc->sc_iomem_alloc; 594 limit = sc->sc_iomem_base + sc->sc_iomem_size; 595 size &= ~0xF; 596 } 597 mask = ~size; 598 size = mask + 1; 599 600 /* Sanity check (must be a power of 2) */ 601 if (size & mask) 602 return (width); 603 604 addr = (*allocp + mask) & ~mask; 605 if ((*allocp = addr + size) > limit) 606 return (-1); 607 608 if (bootverbose) 609 printf("PCI %u:%u:%u: reg %x: size=%08x: addr=%08x\n", 610 bus, slot, func, reg, size, addr); 611 612 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); 613 if (width == 2) 614 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg + 4, 615 0, 4); 616 617 return (width); 618 } 619 620 static void 621 pcib_mbus_init_bridge(struct pcib_mbus_softc *sc, int bus, int slot, int func) 622 { 623 bus_addr_t io_base, mem_base; 624 uint32_t io_limit, mem_limit; 625 int secbus; 626 627 io_base = sc->sc_info->op_io_base; 628 io_limit = io_base + sc->sc_info->op_io_size - 1; 629 mem_base = sc->sc_info->op_mem_base; 630 mem_limit = mem_base + sc->sc_info->op_mem_size - 1; 631 632 /* Configure I/O decode registers */ 633 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEL_1, 634 io_base >> 8, 1); 635 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEH_1, 636 io_base >> 16, 2); 637 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITL_1, 638 io_limit >> 8, 1); 639 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITH_1, 640 io_limit >> 16, 2); 641 642 /* Configure memory decode registers */ 643 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMBASE_1, 644 mem_base >> 16, 2); 645 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMLIMIT_1, 646 mem_limit >> 16, 2); 647 648 /* Disable memory prefetch decode */ 649 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEL_1, 650 0x10, 2); 651 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEH_1, 652 0x0, 4); 653 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITL_1, 654 0xF, 2); 655 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITH_1, 656 0x0, 4); 657 658 secbus = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, 659 PCIR_SECBUS_1, 1); 660 661 /* Configure buses behind the bridge */ 662 pcib_mbus_init(sc, secbus, PCI_SLOTMAX); 663 } 664 665 static int 666 pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot, 667 int func, int hdrtype) 668 { 669 const struct obio_pci_irq_map *map = sc->sc_info->op_pci_irq_map; 670 int maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6; 671 int bar = 0, irq = -1; 672 int pin, i; 673 674 /* Program the base address registers */ 675 while (bar < maxbar) { 676 i = pcib_mbus_init_bar(sc, bus, slot, func, bar); 677 bar += i; 678 if (i < 0) { 679 device_printf(sc->sc_dev, 680 "PCI IO/Memory space exhausted\n"); 681 return (ENOMEM); 682 } 683 } 684 685 /* Perform interrupt routing */ 686 pin = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, 687 PCIR_INTPIN, 1); 688 689 if (map != NULL) 690 while (map->opim_irq >= 0) { 691 if ((map->opim_slot == slot || map->opim_slot < 0) && 692 (map->opim_pin == pin || map->opim_pin < 0)) 693 irq = map->opim_irq; 694 695 map++; 696 } 697 else 698 irq = sc->sc_info->op_irq; 699 700 if (irq >= 0) 701 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 702 PCIR_INTLINE, irq, 1); 703 else { 704 device_printf(sc->sc_dev, "Missing IRQ routing information " 705 "for PCI device %u:%u:%u\n", bus, slot, func); 706 return (ENXIO); 707 } 708 709 return (0); 710 } 711 712 static int 713 pcib_mbus_init(struct pcib_mbus_softc *sc, int bus, int maxslot) 714 { 715 int slot, func, maxfunc, error; 716 uint8_t hdrtype, command, class, subclass; 717 718 for (slot = 0; slot <= maxslot; slot++) { 719 maxfunc = 0; 720 for (func = 0; func <= maxfunc; func++) { 721 hdrtype = pcib_mbus_read_config(sc->sc_dev, bus, slot, 722 func, PCIR_HDRTYPE, 1); 723 724 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) 725 continue; 726 727 if (func == 0 && (hdrtype & PCIM_MFDEV)) 728 maxfunc = PCI_FUNCMAX; 729 730 command = pcib_mbus_read_config(sc->sc_dev, bus, slot, 731 func, PCIR_COMMAND, 1); 732 command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN); 733 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 734 PCIR_COMMAND, command, 1); 735 736 error = pcib_mbus_init_resources(sc, bus, slot, func, 737 hdrtype); 738 739 if (error) 740 return (error); 741 742 command |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 743 PCIM_CMD_PORTEN; 744 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 745 PCIR_COMMAND, command, 1); 746 747 /* Handle PCI-PCI bridges */ 748 class = pcib_mbus_read_config(sc->sc_dev, bus, slot, 749 func, PCIR_CLASS, 1); 750 subclass = pcib_mbus_read_config(sc->sc_dev, bus, slot, 751 func, PCIR_SUBCLASS, 1); 752 753 if (class != PCIC_BRIDGE || 754 subclass != PCIS_BRIDGE_PCI) 755 continue; 756 757 pcib_mbus_init_bridge(sc, bus, slot, func); 758 } 759 } 760 761 /* Enable all ABCD interrupts */ 762 pcib_write_irq_mask(sc, (0xF << 24)); 763 764 return (0); 765 } 766 767 static struct resource * 768 pcib_mbus_alloc_resource(device_t dev, device_t child, int type, int *rid, 769 u_long start, u_long end, u_long count, u_int flags) 770 { 771 struct pcib_mbus_softc *sc = device_get_softc(dev); 772 struct rman *rm = NULL; 773 struct resource *res; 774 775 switch (type) { 776 case SYS_RES_IOPORT: 777 rm = &sc->sc_ioport_rman; 778 break; 779 case SYS_RES_MEMORY: 780 rm = &sc->sc_iomem_rman; 781 break; 782 default: 783 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 784 type, rid, start, end, count, flags)); 785 }; 786 787 res = rman_reserve_resource(rm, start, end, count, flags, child); 788 if (res == NULL) 789 return (NULL); 790 791 rman_set_rid(res, *rid); 792 rman_set_bustag(res, obio_tag); 793 rman_set_bushandle(res, start); 794 795 if (flags & RF_ACTIVE) 796 if (bus_activate_resource(child, type, *rid, res)) { 797 rman_release_resource(res); 798 return (NULL); 799 } 800 801 return (res); 802 } 803 804 static int 805 pcib_mbus_release_resource(device_t dev, device_t child, int type, int rid, 806 struct resource *res) 807 { 808 809 if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) 810 return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 811 type, rid, res)); 812 813 return (rman_release_resource(res)); 814 } 815 816 static int 817 pcib_mbus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 818 { 819 struct pcib_mbus_softc *sc = device_get_softc(dev); 820 821 switch (which) { 822 case PCIB_IVAR_BUS: 823 *result = sc->sc_busnr; 824 return (0); 825 case PCIB_IVAR_DOMAIN: 826 *result = device_get_unit(dev); 827 return (0); 828 } 829 830 return (ENOENT); 831 } 832 833 static int 834 pcib_mbus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 835 { 836 struct pcib_mbus_softc *sc = device_get_softc(dev); 837 838 switch (which) { 839 case PCIB_IVAR_BUS: 840 sc->sc_busnr = value; 841 return (0); 842 } 843 844 return (ENOENT); 845 } 846