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_BUS_OFFS 8 84 #define STATUS_BUS_MASK (0xFF << STATUS_BUS_OFFS) 85 #define STATUS_DEV_OFFS 16 86 #define STATUS_DEV_MASK (0x1F << STATUS_DEV_OFFS) 87 88 #define P2P_CONF_BUS_OFFS 16 89 #define P2P_CONF_BUS_MASK (0xFF << P2P_CONF_BUS_OFFS) 90 #define P2P_CONF_DEV_OFFS 24 91 #define P2P_CONF_DEV_MASK (0x1F << P2P_CONF_DEV_OFFS) 92 93 #define PCI_VENDORID_MRVL 0x11AB 94 95 struct pcib_mbus_softc { 96 device_t sc_dev; 97 98 bus_addr_t sc_iomem_base; 99 bus_addr_t sc_iomem_size; 100 bus_addr_t sc_iomem_alloc; /* Next allocation. */ 101 102 bus_addr_t sc_ioport_base; 103 bus_addr_t sc_ioport_size; 104 bus_addr_t sc_ioport_alloc; /* Next allocation. */ 105 106 struct resource *sc_res; 107 bus_space_handle_t sc_bsh; 108 bus_space_tag_t sc_bst; 109 int sc_rid; 110 111 int sc_busnr; /* Host bridge bus number */ 112 int sc_devnr; /* Host bridge device number */ 113 114 const struct obio_pci *sc_info; 115 }; 116 117 static void pcib_mbus_identify(driver_t *driver, device_t parent); 118 static int pcib_mbus_probe(device_t); 119 static int pcib_mbus_attach(device_t); 120 121 static struct resource *pcib_mbus_alloc_resource(device_t, device_t, int, int *, 122 u_long, u_long, u_long, u_int); 123 static int pcib_mbus_release_resource(device_t, device_t, int, int, 124 struct resource *); 125 static int pcib_mbus_read_ivar(device_t, device_t, int, uintptr_t *); 126 static int pcib_mbus_write_ivar(device_t, device_t, int, uintptr_t); 127 128 static int pcib_mbus_maxslots(device_t); 129 static uint32_t pcib_mbus_read_config(device_t, u_int, u_int, u_int, u_int, 130 int); 131 static void pcib_mbus_write_config(device_t, u_int, u_int, u_int, u_int, 132 uint32_t, int); 133 static int pcib_mbus_init(struct pcib_mbus_softc *sc, int bus, int maxslot); 134 static int pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, 135 int func, int barno); 136 static void pcib_mbus_init_bridge(struct pcib_mbus_softc *sc, int bus, int slot, 137 int func); 138 static int pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, 139 int slot, int func, int hdrtype); 140 141 /* 142 * Bus interface definitions. 143 */ 144 static device_method_t pcib_mbus_methods[] = { 145 /* Device interface */ 146 DEVMETHOD(device_identify, pcib_mbus_identify), 147 DEVMETHOD(device_probe, pcib_mbus_probe), 148 DEVMETHOD(device_attach, pcib_mbus_attach), 149 150 /* Bus interface */ 151 DEVMETHOD(bus_print_child, bus_generic_print_child), 152 DEVMETHOD(bus_read_ivar, pcib_mbus_read_ivar), 153 DEVMETHOD(bus_write_ivar, pcib_mbus_write_ivar), 154 DEVMETHOD(bus_alloc_resource, pcib_mbus_alloc_resource), 155 DEVMETHOD(bus_release_resource, pcib_mbus_release_resource), 156 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 157 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 158 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 159 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 160 161 /* pcib interface */ 162 DEVMETHOD(pcib_maxslots, pcib_mbus_maxslots), 163 DEVMETHOD(pcib_read_config, pcib_mbus_read_config), 164 DEVMETHOD(pcib_write_config, pcib_mbus_write_config), 165 DEVMETHOD(pcib_route_interrupt, pcib_route_interrupt), 166 167 { 0, 0 } 168 }; 169 170 static driver_t pcib_mbus_driver = { 171 "pcib", 172 pcib_mbus_methods, 173 sizeof(struct pcib_mbus_softc), 174 }; 175 176 devclass_t pcib_devclass; 177 178 DRIVER_MODULE(pcib, mbus, pcib_mbus_driver, pcib_devclass, 0, 0); 179 180 static struct mtx pcicfg_mtx; 181 182 static inline void 183 pcib_write_irq_mask(struct pcib_mbus_softc *sc, uint32_t mask) 184 { 185 186 if (!sc->sc_info->op_type != MV_TYPE_PCI) 187 return; 188 189 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 190 PCIE_REG_IRQ_MASK, mask); 191 } 192 193 static void 194 pcib_mbus_hw_cfginit(void) 195 { 196 static int opened = 0; 197 198 if (opened) 199 return; 200 201 mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN); 202 opened = 1; 203 } 204 205 static uint32_t 206 pcib_mbus_hw_cfgread(struct pcib_mbus_softc *sc, u_int bus, u_int slot, 207 u_int func, u_int reg, int bytes) 208 { 209 uint32_t addr, data, ca, cd; 210 211 ca = (sc->sc_info->op_type != MV_TYPE_PCI) ? 212 PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR; 213 cd = (sc->sc_info->op_type != MV_TYPE_PCI) ? 214 PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA; 215 addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | 216 PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg); 217 218 mtx_lock_spin(&pcicfg_mtx); 219 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr); 220 221 data = ~0; 222 switch (bytes) { 223 case 1: 224 data = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 225 cd + (reg & 3)); 226 break; 227 case 2: 228 data = le16toh(bus_space_read_2(sc->sc_bst, sc->sc_bsh, 229 cd + (reg & 2))); 230 break; 231 case 4: 232 data = le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 233 cd)); 234 break; 235 } 236 mtx_unlock_spin(&pcicfg_mtx); 237 return (data); 238 } 239 240 static void 241 pcib_mbus_hw_cfgwrite(struct pcib_mbus_softc *sc, u_int bus, u_int slot, 242 u_int func, u_int reg, uint32_t data, int bytes) 243 { 244 uint32_t addr, ca, cd; 245 246 ca = (sc->sc_info->op_type != MV_TYPE_PCI) ? 247 PCIE_REG_CFG_ADDR : PCI_REG_CFG_ADDR; 248 cd = (sc->sc_info->op_type != MV_TYPE_PCI) ? 249 PCIE_REG_CFG_DATA : PCI_REG_CFG_DATA; 250 addr = PCI_CFG_ENA | PCI_CFG_BUS(bus) | PCI_CFG_DEV(slot) | 251 PCI_CFG_FUN(func) | PCI_CFG_PCIE_REG(reg); 252 253 mtx_lock_spin(&pcicfg_mtx); 254 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ca, addr); 255 256 switch (bytes) { 257 case 1: 258 bus_space_write_1(sc->sc_bst, sc->sc_bsh, 259 cd + (reg & 3), data); 260 break; 261 case 2: 262 bus_space_write_2(sc->sc_bst, sc->sc_bsh, 263 cd + (reg & 2), htole16(data)); 264 break; 265 case 4: 266 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 267 cd, htole32(data)); 268 break; 269 } 270 mtx_unlock_spin(&pcicfg_mtx); 271 } 272 273 static int 274 pcib_mbus_maxslots(device_t dev) 275 { 276 struct pcib_mbus_softc *sc = device_get_softc(dev); 277 278 return ((sc->sc_info->op_type != MV_TYPE_PCI) ? 1 : PCI_SLOTMAX); 279 } 280 281 static uint32_t 282 pcib_mbus_read_config(device_t dev, u_int bus, u_int slot, u_int func, 283 u_int reg, int bytes) 284 { 285 struct pcib_mbus_softc *sc = device_get_softc(dev); 286 287 /* Skip self */ 288 if (bus == sc->sc_busnr && slot == sc->sc_devnr) 289 return (~0U); 290 291 return (pcib_mbus_hw_cfgread(sc, bus, slot, func, reg, bytes)); 292 } 293 294 static void 295 pcib_mbus_write_config(device_t dev, u_int bus, u_int slot, u_int func, 296 u_int reg, uint32_t val, int bytes) 297 { 298 struct pcib_mbus_softc *sc = device_get_softc(dev); 299 300 /* Skip self */ 301 if (bus == sc->sc_busnr && slot == sc->sc_devnr) 302 return; 303 304 pcib_mbus_hw_cfgwrite(sc, bus, slot, func, reg, val, bytes); 305 } 306 307 static void 308 pcib_mbus_add_child(driver_t *driver, device_t parent, struct pcib_mbus_softc *sc) 309 { 310 device_t child; 311 int error; 312 313 /* Configure CPU decoding windows */ 314 error = decode_win_cpu_set(sc->sc_info->op_io_win_target, 315 sc->sc_info->op_io_win_attr, sc->sc_info->op_io_base, 316 sc->sc_info->op_io_size, -1); 317 if (error < 0) { 318 device_printf(parent, "Could not set up CPU decode " 319 "window for PCI IO\n"); 320 return; 321 } 322 error = decode_win_cpu_set(sc->sc_info->op_mem_win_target, 323 sc->sc_info->op_mem_win_attr, sc->sc_info->op_mem_base, 324 sc->sc_info->op_mem_size, -1); 325 if (error < 0) { 326 device_printf(parent, "Could not set up CPU decode " 327 "windows for PCI MEM\n"); 328 return; 329 } 330 331 /* Create driver instance */ 332 child = BUS_ADD_CHILD(parent, 0, driver->name, -1); 333 bus_set_resource(child, SYS_RES_MEMORY, 0, 334 sc->sc_info->op_base, sc->sc_info->op_size); 335 device_set_softc(child, sc); 336 } 337 338 static void 339 pcib_mbus_identify(driver_t *driver, device_t parent) 340 { 341 const struct obio_pci *info = mv_pci_info; 342 struct pcib_mbus_softc *sc; 343 uint32_t control; 344 345 while (info->op_base) { 346 sc = malloc(driver->size, M_DEVBUF, M_NOWAIT | M_ZERO); 347 if (sc == NULL) { 348 device_printf(parent, "Could not allocate pcib " 349 "memory\n"); 350 break; 351 } 352 sc->sc_info = info++; 353 354 /* 355 * PCI bridge objects are instantiated immediately. PCI-Express 356 * bridges require more complicated handling depending on 357 * platform configuration. 358 */ 359 if (sc->sc_info->op_type == MV_TYPE_PCI) { 360 pcib_mbus_add_child(driver, parent, sc); 361 continue; 362 } 363 364 /* 365 * Read link configuration 366 */ 367 sc->sc_rid = 0; 368 sc->sc_res = BUS_ALLOC_RESOURCE(parent, parent, SYS_RES_MEMORY, 369 &sc->sc_rid, sc->sc_info->op_base, sc->sc_info->op_base + 370 sc->sc_info->op_size - 1, sc->sc_info->op_size, 371 RF_ACTIVE); 372 if (sc->sc_res == NULL) { 373 device_printf(parent, "Could not map pcib memory\n"); 374 break; 375 } 376 377 sc->sc_bst = rman_get_bustag(sc->sc_res); 378 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 379 380 control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 381 PCIE_REG_CONTROL); 382 383 BUS_RELEASE_RESOURCE(parent, parent, SYS_RES_MEMORY, sc->sc_rid, 384 sc->sc_res); 385 386 /* 387 * If this PCI-E port (controller) is configured (by the 388 * underlying firmware) with lane width other than 1x, there 389 * are auxiliary resources defined for aggregating more width 390 * on our lane. Skip all such entries as they are not 391 * standalone ports and must not have a device object 392 * instantiated. 393 */ 394 if ((control & PCIE_CTRL_LINK1X) == 0) 395 while (info->op_base && 396 info->op_type == MV_TYPE_PCIE_AGGR_LANE) 397 info++; 398 399 pcib_mbus_add_child(driver, parent, sc); 400 } 401 } 402 403 static int 404 pcib_mbus_probe(device_t self) 405 { 406 char buf[128]; 407 struct pcib_mbus_softc *sc; 408 const char *id, *type; 409 uint32_t val; 410 int rv = ENOENT, bus, dev; 411 412 sc = device_get_softc(self); 413 414 sc->sc_rid = 0; 415 sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid, 416 RF_ACTIVE); 417 if (sc->sc_res == NULL) { 418 device_printf(self, "Could not map memory\n"); 419 return (ENXIO); 420 } 421 422 sc->sc_bst = rman_get_bustag(sc->sc_res); 423 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 424 425 pcib_mbus_hw_cfginit(); 426 427 /* Retrieve configuration of the bridge */ 428 if (sc->sc_info->op_type == MV_TYPE_PCI) { 429 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 430 PCI_REG_P2P_CONF); 431 bus = sc->sc_busnr = (val & P2P_CONF_BUS_MASK) >> 432 P2P_CONF_BUS_OFFS; 433 dev = sc->sc_devnr = (val & P2P_CONF_DEV_MASK) >> 434 P2P_CONF_DEV_OFFS; 435 } else { 436 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS); 437 bus = sc->sc_busnr = (val & STATUS_BUS_MASK) >> STATUS_BUS_OFFS; 438 dev = sc->sc_devnr = (val & STATUS_DEV_MASK) >> STATUS_DEV_OFFS; 439 } 440 441 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_VENDOR, 2); 442 if (val != PCI_VENDORID_MRVL) 443 goto out; 444 445 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_DEVICE, 2); 446 switch (val) { 447 case 0x5281: 448 id = "88F5281"; 449 break; 450 case 0x5182: 451 id = "88F5182"; 452 break; 453 case 0x6281: 454 id = "88F6281"; 455 break; 456 case 0x6381: 457 id = "MV78100"; 458 break; 459 default: 460 device_printf(self, "unknown Marvell PCI bridge: %x\n", val); 461 goto out; 462 } 463 464 type = "PCI"; 465 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_CAP_PTR, 1); 466 while (val != 0) { 467 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, val, 2); 468 switch (val & 0xff) { 469 case PCIY_PCIX: 470 type = "PCI-X"; 471 break; 472 case PCIY_EXPRESS: 473 type = "PCI-Express"; 474 break; 475 } 476 val = (val >> 8) & 0xff; 477 } 478 479 snprintf(buf, sizeof(buf), "Marvell %s %s host controller", id, 480 type); 481 device_set_desc_copy(self, buf); 482 rv = BUS_PROBE_DEFAULT; 483 out: 484 bus_release_resource(self, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res); 485 return (rv); 486 } 487 488 static int 489 pcib_mbus_attach(device_t self) 490 { 491 struct pcib_mbus_softc *sc; 492 uint32_t val; 493 int err; 494 495 sc = device_get_softc(self); 496 sc->sc_dev = self; 497 498 sc->sc_rid = 0; 499 sc->sc_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &sc->sc_rid, 500 RF_ACTIVE); 501 if (sc->sc_res == NULL) { 502 device_printf(self, "Could not map memory\n"); 503 return (ENXIO); 504 } 505 sc->sc_bst = rman_get_bustag(sc->sc_res); 506 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 507 508 /* Enable PCI bridge */ 509 val = pcib_mbus_hw_cfgread(sc, sc->sc_busnr, sc->sc_devnr, 0, 510 PCIR_COMMAND, 2); 511 val |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 512 PCIM_CMD_PORTEN; 513 pcib_mbus_hw_cfgwrite(sc, sc->sc_busnr, sc->sc_devnr, 0, 514 PCIR_COMMAND, val, 2); 515 516 sc->sc_iomem_base = sc->sc_info->op_mem_base; 517 sc->sc_iomem_size = sc->sc_info->op_mem_size; 518 sc->sc_iomem_alloc = sc->sc_info->op_mem_base; 519 520 sc->sc_ioport_base = sc->sc_info->op_io_base; 521 sc->sc_ioport_size = sc->sc_info->op_io_size; 522 sc->sc_ioport_alloc = sc->sc_info->op_io_base; 523 524 err = pcib_mbus_init(sc, sc->sc_busnr, pcib_mbus_maxslots(sc->sc_dev)); 525 if (err) 526 return(err); 527 528 device_add_child(self, "pci", -1); 529 return (bus_generic_attach(self)); 530 } 531 532 static int 533 pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, int func, 534 int barno) 535 { 536 bus_addr_t *allocp, limit; 537 uint32_t addr, bar, mask, size; 538 int reg, width; 539 540 reg = PCIR_BAR(barno); 541 bar = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, reg, 4); 542 if (bar == 0) 543 return (1); 544 545 /* Calculate BAR size: 64 or 32 bit (in 32-bit units) */ 546 width = ((bar & 7) == 4) ? 2 : 1; 547 548 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4); 549 size = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, reg, 4); 550 551 /* Get BAR type and size */ 552 if (bar & 1) { 553 /* I/O port */ 554 allocp = &sc->sc_ioport_alloc; 555 limit = sc->sc_ioport_base + sc->sc_ioport_size; 556 size &= ~0x3; 557 if ((size & 0xffff0000) == 0) 558 size |= 0xffff0000; 559 } else { 560 /* Memory */ 561 allocp = &sc->sc_iomem_alloc; 562 limit = sc->sc_iomem_base + sc->sc_iomem_size; 563 size &= ~0xF; 564 } 565 mask = ~size; 566 size = mask + 1; 567 568 /* Sanity check (must be a power of 2) */ 569 if (size & mask) 570 return (width); 571 572 addr = (*allocp + mask) & ~mask; 573 if ((*allocp = addr + size) >= limit) 574 return (-1); 575 576 if (bootverbose) 577 printf("PCI %u:%u:%u: reg %x: size=%08x: addr=%08x\n", 578 bus, slot, func, reg, size, addr); 579 580 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); 581 if (width == 2) 582 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg + 4, 583 0, 4); 584 585 return (width); 586 } 587 588 static void 589 pcib_mbus_init_bridge(struct pcib_mbus_softc *sc, int bus, int slot, int func) 590 { 591 bus_addr_t io_base, mem_base; 592 uint32_t io_limit, mem_limit; 593 int secbus; 594 595 io_base = sc->sc_info->op_io_base; 596 io_limit = io_base + sc->sc_info->op_io_size - 1; 597 mem_base = sc->sc_info->op_mem_base; 598 mem_limit = mem_base + sc->sc_info->op_mem_size - 1; 599 600 /* Configure I/O decode registers */ 601 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEL_1, 602 io_base >> 8, 1); 603 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEH_1, 604 io_base >> 16, 2); 605 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITL_1, 606 io_limit >> 8, 1); 607 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITH_1, 608 io_limit >> 16, 2); 609 610 /* Configure memory decode registers */ 611 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMBASE_1, 612 mem_base >> 16, 2); 613 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMLIMIT_1, 614 mem_limit >> 16, 2); 615 616 /* Disable memory prefetch decode */ 617 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEL_1, 618 0x10, 2); 619 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMBASEH_1, 620 0x0, 4); 621 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITL_1, 622 0xF, 2); 623 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_PMLIMITH_1, 624 0x0, 4); 625 626 secbus = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, 627 PCIR_SECBUS_1, 1); 628 629 /* Configure buses behind the bridge */ 630 pcib_mbus_init(sc, secbus, PCI_SLOTMAX); 631 } 632 633 static int 634 pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot, 635 int func, int hdrtype) 636 { 637 int maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6; 638 int bar = 0, irq, pin, i; 639 640 /* Program the base address registers */ 641 while (bar < maxbar) { 642 i = pcib_mbus_init_bar(sc, bus, slot, func, bar); 643 bar += i; 644 if (i < 0) { 645 device_printf(sc->sc_dev, 646 "PCI IO/Memory space exhausted\n"); 647 return (ENOMEM); 648 } 649 } 650 651 /* Perform interrupt routing */ 652 pin = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, 653 PCIR_INTPIN, 1); 654 655 if (sc->sc_info->op_get_irq != NULL) 656 irq = sc->sc_info->op_get_irq(bus, slot, func, pin); 657 else 658 irq = sc->sc_info->op_irq; 659 660 if (irq >= 0) 661 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 662 PCIR_INTLINE, irq, 1); 663 else { 664 device_printf(sc->sc_dev, "Missing IRQ routing information " 665 "for PCI device %u:%u:%u\n", bus, slot, func); 666 return (ENXIO); 667 } 668 669 return (0); 670 } 671 672 static int 673 pcib_mbus_init(struct pcib_mbus_softc *sc, int bus, int maxslot) 674 { 675 int slot, func, maxfunc, error; 676 uint8_t hdrtype, command, class, subclass; 677 678 for (slot = 0; slot <= maxslot; slot++) { 679 maxfunc = 0; 680 for (func = 0; func <= maxfunc; func++) { 681 hdrtype = pcib_mbus_read_config(sc->sc_dev, bus, slot, 682 func, PCIR_HDRTYPE, 1); 683 684 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) 685 continue; 686 687 if (func == 0 && (hdrtype & PCIM_MFDEV)) 688 maxfunc = PCI_FUNCMAX; 689 690 command = pcib_mbus_read_config(sc->sc_dev, bus, slot, 691 func, PCIR_COMMAND, 1); 692 command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN); 693 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 694 PCIR_COMMAND, command, 1); 695 696 error = pcib_mbus_init_resources(sc, bus, slot, func, 697 hdrtype); 698 699 if (error) 700 return (error); 701 702 command |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 703 PCIM_CMD_PORTEN; 704 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 705 PCIR_COMMAND, command, 1); 706 707 /* Handle PCI-PCI bridges */ 708 class = pcib_mbus_read_config(sc->sc_dev, bus, slot, 709 func, PCIR_CLASS, 1); 710 subclass = pcib_mbus_read_config(sc->sc_dev, bus, slot, 711 func, PCIR_SUBCLASS, 1); 712 713 if (class != PCIC_BRIDGE || 714 subclass != PCIS_BRIDGE_PCI) 715 continue; 716 717 pcib_mbus_init_bridge(sc, bus, slot, func); 718 } 719 } 720 721 /* Enable all ABCD interrupts */ 722 pcib_write_irq_mask(sc, (0xF << 24)); 723 724 return (0); 725 } 726 727 static struct resource * 728 pcib_mbus_alloc_resource(device_t dev, device_t child, int type, int *rid, 729 u_long start, u_long end, u_long count, u_int flags) 730 { 731 732 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 733 type, rid, start, end, count, flags)); 734 } 735 736 static int 737 pcib_mbus_release_resource(device_t dev, device_t child, int type, int rid, 738 struct resource *res) 739 { 740 741 return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 742 type, rid, res)); 743 } 744 745 static int 746 pcib_mbus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 747 { 748 struct pcib_mbus_softc *sc = device_get_softc(dev); 749 750 switch (which) { 751 case PCIB_IVAR_BUS: 752 *result = sc->sc_busnr; 753 return (0); 754 case PCIB_IVAR_DOMAIN: 755 *result = device_get_unit(dev); 756 return (0); 757 } 758 759 return (ENOENT); 760 } 761 762 static int 763 pcib_mbus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 764 { 765 struct pcib_mbus_softc *sc = device_get_softc(dev); 766 767 switch (which) { 768 case PCIB_IVAR_BUS: 769 sc->sc_busnr = value; 770 return (0); 771 } 772 773 return (ENOENT); 774 } 775