1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2019 Michal Meloun <mmel@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29 /* Base class for all Synopsys DesignWare PCI/PCIe drivers */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/bus.h> 37 #include <sys/devmap.h> 38 #include <sys/proc.h> 39 #include <sys/kernel.h> 40 #include <sys/lock.h> 41 #include <sys/malloc.h> 42 #include <sys/module.h> 43 #include <sys/mutex.h> 44 #include <sys/rman.h> 45 46 #include <machine/bus.h> 47 #include <machine/intr.h> 48 #include <machine/resource.h> 49 50 #include <dev/ofw/ofw_bus.h> 51 #include <dev/ofw/ofw_bus_subr.h> 52 #include <dev/ofw/ofw_pci.h> 53 #include <dev/ofw/ofwpci.h> 54 #include <dev/pci/pcivar.h> 55 #include <dev/pci/pcireg.h> 56 #include <dev/pci/pcib_private.h> 57 #include <dev/pci/pci_dw.h> 58 59 #include "pcib_if.h" 60 #include "pci_dw_if.h" 61 62 #define DEBUG 63 #ifdef DEBUG 64 #define debugf(fmt, args...) do { printf(fmt,##args); } while (0) 65 #else 66 #define debugf(fmt, args...) 67 #endif 68 69 #define DBI_WR1(sc, reg, val) pci_dw_dbi_wr1((sc)->dev, reg, val) 70 #define DBI_WR2(sc, reg, val) pci_dw_dbi_wr2((sc)->dev, reg, val) 71 #define DBI_WR4(sc, reg, val) pci_dw_dbi_wr4((sc)->dev, reg, val) 72 #define DBI_RD1(sc, reg) pci_dw_dbi_rd1((sc)->dev, reg) 73 #define DBI_RD2(sc, reg) pci_dw_dbi_rd2((sc)->dev, reg) 74 #define DBI_RD4(sc, reg) pci_dw_dbi_rd4((sc)->dev, reg) 75 76 #define PCI_BUS_SHIFT 20 77 #define PCI_SLOT_SHIFT 15 78 #define PCI_FUNC_SHIFT 12 79 #define PCI_BUS_MASK 0xFF 80 #define PCI_SLOT_MASK 0x1F 81 #define PCI_FUNC_MASK 0x07 82 #define PCI_REG_MASK 0xFFF 83 84 #define IATU_CFG_BUS(bus) ((uint64_t)((bus) & 0xff) << 24) 85 #define IATU_CFG_SLOT(slot) ((uint64_t)((slot) & 0x1f) << 19) 86 #define IATU_CFG_FUNC(func) ((uint64_t)((func) & 0x07) << 16) 87 88 static uint32_t 89 pci_dw_dbi_read(device_t dev, u_int reg, int width) 90 { 91 struct pci_dw_softc *sc; 92 93 sc = device_get_softc(dev); 94 MPASS(sc->dbi_res != NULL); 95 96 switch (width) { 97 case 4: 98 return (bus_read_4(sc->dbi_res, reg)); 99 case 2: 100 return (bus_read_2(sc->dbi_res, reg)); 101 case 1: 102 return (bus_read_1(sc->dbi_res, reg)); 103 default: 104 device_printf(sc->dev, "Unsupported width: %d\n", width); 105 return (0xFFFFFFFF); 106 } 107 } 108 109 static void 110 pci_dw_dbi_write(device_t dev, u_int reg, uint32_t val, int width) 111 { 112 struct pci_dw_softc *sc; 113 114 sc = device_get_softc(dev); 115 MPASS(sc->dbi_res != NULL); 116 117 switch (width) { 118 case 4: 119 bus_write_4(sc->dbi_res, reg, val); 120 break; 121 case 2: 122 bus_write_2(sc->dbi_res, reg, val); 123 break; 124 case 1: 125 bus_write_1(sc->dbi_res, reg, val); 126 break; 127 default: 128 device_printf(sc->dev, "Unsupported width: %d\n", width); 129 break; 130 } 131 } 132 133 static void 134 pci_dw_dbi_protect(struct pci_dw_softc *sc, bool protect) 135 { 136 uint32_t reg; 137 138 reg = DBI_RD4(sc, DW_MISC_CONTROL_1); 139 if (protect) 140 reg &= ~DBI_RO_WR_EN; 141 else 142 reg |= DBI_RO_WR_EN; 143 DBI_WR4(sc, DW_MISC_CONTROL_1, reg); 144 } 145 146 static bool 147 pci_dw_check_dev(struct pci_dw_softc *sc, u_int bus, u_int slot, u_int func, 148 u_int reg) 149 { 150 bool status; 151 int rv; 152 153 if (bus < sc->bus_start || bus > sc->bus_end || slot > PCI_SLOTMAX || 154 func > PCI_FUNCMAX || reg > PCIE_REGMAX) 155 return (false); 156 157 /* link is needed for access to all non-root busses */ 158 if (bus != sc->root_bus) { 159 rv = PCI_DW_GET_LINK(sc->dev, &status); 160 if (rv != 0 || !status) 161 return (false); 162 return (true); 163 } 164 165 /* we have only 1 device with 1 function root port */ 166 if (slot > 0 || func > 0) 167 return (false); 168 return (true); 169 } 170 171 /* Map one uoutbound ATU region */ 172 static int 173 pci_dw_map_out_atu(struct pci_dw_softc *sc, int idx, int type, 174 uint64_t pa, uint64_t pci_addr, uint32_t size) 175 { 176 uint32_t reg; 177 int i; 178 179 if (size == 0) 180 return (0); 181 182 DBI_WR4(sc, DW_IATU_VIEWPORT, IATU_REGION_INDEX(idx)); 183 DBI_WR4(sc, DW_IATU_LWR_BASE_ADDR, pa & 0xFFFFFFFF); 184 DBI_WR4(sc, DW_IATU_UPPER_BASE_ADDR, (pa >> 32) & 0xFFFFFFFF); 185 DBI_WR4(sc, DW_IATU_LIMIT_ADDR, (pa + size - 1) & 0xFFFFFFFF); 186 DBI_WR4(sc, DW_IATU_LWR_TARGET_ADDR, pci_addr & 0xFFFFFFFF); 187 DBI_WR4(sc, DW_IATU_UPPER_TARGET_ADDR, (pci_addr >> 32) & 0xFFFFFFFF); 188 DBI_WR4(sc, DW_IATU_CTRL1, IATU_CTRL1_TYPE(type)); 189 DBI_WR4(sc, DW_IATU_CTRL2, IATU_CTRL2_REGION_EN); 190 191 /* Wait until setup becomes valid */ 192 for (i = 10; i > 0; i--) { 193 reg = DBI_RD4(sc, DW_IATU_CTRL2); 194 if (reg & IATU_CTRL2_REGION_EN) 195 return (0); 196 DELAY(5); 197 } 198 device_printf(sc->dev, 199 "Cannot map outbound region(%d) in iATU\n", idx); 200 return (ETIMEDOUT); 201 } 202 203 static int 204 pci_dw_setup_hw(struct pci_dw_softc *sc) 205 { 206 uint32_t reg; 207 int rv; 208 209 pci_dw_dbi_protect(sc, false); 210 211 /* Setup config registers */ 212 DBI_WR1(sc, PCIR_CLASS, PCIC_BRIDGE); 213 DBI_WR1(sc, PCIR_SUBCLASS, PCIS_BRIDGE_PCI); 214 DBI_WR4(sc, PCIR_BAR(0), 4); 215 DBI_WR4(sc, PCIR_BAR(1), 0); 216 DBI_WR1(sc, PCIR_INTPIN, 1); 217 DBI_WR1(sc, PCIR_PRIBUS_1, sc->root_bus); 218 DBI_WR1(sc, PCIR_SECBUS_1, sc->sub_bus); 219 DBI_WR1(sc, PCIR_SUBBUS_1, sc->bus_end); 220 DBI_WR2(sc, PCIR_COMMAND, 221 PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | 222 PCIM_CMD_BUSMASTEREN | PCIM_CMD_SERRESPEN); 223 pci_dw_dbi_protect(sc, true); 224 225 /* Setup outbound memory window */ 226 rv = pci_dw_map_out_atu(sc, 0, IATU_CTRL1_TYPE_MEM, 227 sc->mem_range.host, sc->mem_range.pci, sc->mem_range.size); 228 if (rv != 0) 229 return (rv); 230 231 /* If we have enouht viewports ..*/ 232 if (sc->num_viewport >= 3 && sc->io_range.size != 0) { 233 /* Setup outbound I/O window */ 234 rv = pci_dw_map_out_atu(sc, 0, IATU_CTRL1_TYPE_MEM, 235 sc->io_range.host, sc->io_range.pci, sc->io_range.size); 236 if (rv != 0) 237 return (rv); 238 } 239 /* XXX Should we handle also prefetch memory? */ 240 241 /* Adjust number of lanes */ 242 reg = DBI_RD4(sc, DW_PORT_LINK_CTRL); 243 reg &= ~PORT_LINK_CAPABLE(~0); 244 switch (sc->num_lanes) { 245 case 1: 246 reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_1); 247 break; 248 case 2: 249 reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_2); 250 break; 251 case 4: 252 reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_4); 253 break; 254 case 8: 255 reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_8); 256 break; 257 case 16: 258 reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_16); 259 break; 260 case 32: 261 reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_32); 262 break; 263 default: 264 device_printf(sc->dev, 265 "'num-lanes' property have invalid value: %d\n", 266 sc->num_lanes); 267 return (EINVAL); 268 } 269 DBI_WR4(sc, DW_PORT_LINK_CTRL, reg); 270 271 /* And link width */ 272 reg = DBI_RD4(sc, DW_GEN2_CTRL); 273 reg &= ~GEN2_CTRL_NUM_OF_LANES(~0); 274 switch (sc->num_lanes) { 275 case 1: 276 reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_1); 277 break; 278 case 2: 279 reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_2); 280 break; 281 case 4: 282 reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_4); 283 break; 284 case 8: 285 reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_8); 286 break; 287 case 16: 288 reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_16); 289 break; 290 case 32: 291 reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_32); 292 break; 293 } 294 DBI_WR4(sc, DW_GEN2_CTRL, reg); 295 296 reg = DBI_RD4(sc, DW_GEN2_CTRL); 297 reg |= DIRECT_SPEED_CHANGE; 298 DBI_WR4(sc, DW_GEN2_CTRL, reg); 299 300 return (0); 301 } 302 303 static int 304 pci_dw_decode_ranges(struct pci_dw_softc *sc, struct ofw_pci_range *ranges, 305 int nranges) 306 { 307 int i; 308 309 for (i = 0; i < nranges; i++) { 310 if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == 311 OFW_PCI_PHYS_HI_SPACE_IO) { 312 if (sc->io_range.size != 0) { 313 device_printf(sc->dev, 314 "Duplicated IO range found in DT\n"); 315 return (ENXIO); 316 } 317 sc->io_range = ranges[i]; 318 } 319 if (((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == 320 OFW_PCI_PHYS_HI_SPACE_MEM32)) { 321 if (ranges[i].pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) { 322 if (sc->pref_mem_range.size != 0) { 323 device_printf(sc->dev, 324 "Duplicated memory range found " 325 "in DT\n"); 326 return (ENXIO); 327 } 328 sc->pref_mem_range = ranges[i]; 329 } else { 330 if (sc->mem_range.size != 0) { 331 device_printf(sc->dev, 332 "Duplicated memory range found " 333 "in DT\n"); 334 return (ENXIO); 335 } 336 sc->mem_range = ranges[i]; 337 } 338 } 339 } 340 if (sc->mem_range.size == 0) { 341 device_printf(sc->dev, 342 " Not all required ranges are found in DT\n"); 343 return (ENXIO); 344 } 345 return (0); 346 } 347 348 /*----------------------------------------------------------------------------- 349 * 350 * P C I B I N T E R F A C E 351 */ 352 353 static uint32_t 354 pci_dw_read_config(device_t dev, u_int bus, u_int slot, 355 u_int func, u_int reg, int bytes) 356 { 357 struct pci_dw_softc *sc; 358 struct resource *res; 359 uint32_t data; 360 uint64_t addr; 361 int type, rv; 362 363 sc = device_get_softc(dev); 364 365 if (!pci_dw_check_dev(sc, bus, slot, func, reg)) 366 return (0xFFFFFFFFU); 367 368 if (bus == sc->root_bus) { 369 res = (sc->dbi_res); 370 } else { 371 addr = IATU_CFG_BUS(bus) | IATU_CFG_SLOT(slot) | 372 IATU_CFG_FUNC(func); 373 if (bus == sc->sub_bus) 374 type = IATU_CTRL1_TYPE_CFG0; 375 else 376 type = IATU_CTRL1_TYPE_CFG1; 377 rv = pci_dw_map_out_atu(sc, 1, type, 378 sc->cfg_pa, addr, sc->cfg_size); 379 if (rv != 0) 380 return (0xFFFFFFFFU); 381 res = sc->cfg_res; 382 } 383 384 switch (bytes) { 385 case 1: 386 data = bus_read_1(res, reg); 387 break; 388 case 2: 389 data = bus_read_2(res, reg); 390 break; 391 case 4: 392 data = bus_read_4(res, reg); 393 break; 394 default: 395 data = 0xFFFFFFFFU; 396 } 397 398 return (data); 399 400 } 401 402 static void 403 pci_dw_write_config(device_t dev, u_int bus, u_int slot, 404 u_int func, u_int reg, uint32_t val, int bytes) 405 { 406 struct pci_dw_softc *sc; 407 struct resource *res; 408 uint64_t addr; 409 int type, rv; 410 411 sc = device_get_softc(dev); 412 if (!pci_dw_check_dev(sc, bus, slot, func, reg)) 413 return; 414 415 if (bus == sc->root_bus) { 416 res = (sc->dbi_res); 417 } else { 418 addr = IATU_CFG_BUS(bus) | IATU_CFG_SLOT(slot) | 419 IATU_CFG_FUNC(func); 420 if (bus == sc->sub_bus) 421 type = IATU_CTRL1_TYPE_CFG0; 422 else 423 type = IATU_CTRL1_TYPE_CFG1; 424 rv = pci_dw_map_out_atu(sc, 1, type, 425 sc->cfg_pa, addr, sc->cfg_size); 426 if (rv != 0) 427 return ; 428 res = sc->cfg_res; 429 } 430 431 switch (bytes) { 432 case 1: 433 bus_write_1(res, reg, val); 434 break; 435 case 2: 436 bus_write_2(res, reg, val); 437 break; 438 case 4: 439 bus_write_4(res, reg, val); 440 break; 441 default: 442 break; 443 } 444 } 445 446 static int 447 pci_dw_alloc_msi(device_t pci, device_t child, int count, 448 int maxcount, int *irqs) 449 { 450 phandle_t msi_parent; 451 int rv; 452 453 rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 454 &msi_parent, NULL); 455 if (rv != 0) 456 return (rv); 457 458 return (intr_alloc_msi(pci, child, msi_parent, count, maxcount, 459 irqs)); 460 } 461 462 static int 463 pci_dw_release_msi(device_t pci, device_t child, int count, int *irqs) 464 { 465 phandle_t msi_parent; 466 int rv; 467 468 rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 469 &msi_parent, NULL); 470 if (rv != 0) 471 return (rv); 472 return (intr_release_msi(pci, child, msi_parent, count, irqs)); 473 } 474 475 static int 476 pci_dw_map_msi(device_t pci, device_t child, int irq, uint64_t *addr, 477 uint32_t *data) 478 { 479 phandle_t msi_parent; 480 int rv; 481 482 rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 483 &msi_parent, NULL); 484 if (rv != 0) 485 return (rv); 486 487 return (intr_map_msi(pci, child, msi_parent, irq, addr, data)); 488 } 489 490 static int 491 pci_dw_alloc_msix(device_t pci, device_t child, int *irq) 492 { 493 phandle_t msi_parent; 494 int rv; 495 496 rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 497 &msi_parent, NULL); 498 if (rv != 0) 499 return (rv); 500 return (intr_alloc_msix(pci, child, msi_parent, irq)); 501 } 502 503 static int 504 pci_dw_release_msix(device_t pci, device_t child, int irq) 505 { 506 phandle_t msi_parent; 507 int rv; 508 509 rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), 510 &msi_parent, NULL); 511 if (rv != 0) 512 return (rv); 513 return (intr_release_msix(pci, child, msi_parent, irq)); 514 } 515 516 static int 517 pci_dw_get_id(device_t pci, device_t child, enum pci_id_type type, 518 uintptr_t *id) 519 { 520 phandle_t node; 521 int rv; 522 uint32_t rid; 523 uint16_t pci_rid; 524 525 if (type != PCI_ID_MSI) 526 return (pcib_get_id(pci, child, type, id)); 527 528 node = ofw_bus_get_node(pci); 529 pci_rid = pci_get_rid(child); 530 531 rv = ofw_bus_msimap(node, pci_rid, NULL, &rid); 532 if (rv != 0) 533 return (rv); 534 *id = rid; 535 536 return (0); 537 } 538 539 /*----------------------------------------------------------------------------- 540 * 541 * B U S / D E V I C E I N T E R F A C E 542 */ 543 static bus_dma_tag_t 544 pci_dw_get_dma_tag(device_t dev, device_t child) 545 { 546 struct pci_dw_softc *sc; 547 548 sc = device_get_softc(dev); 549 return (sc->dmat); 550 } 551 552 int 553 pci_dw_init(device_t dev) 554 { 555 struct pci_dw_softc *sc; 556 int rv, rid; 557 558 sc = device_get_softc(dev); 559 sc->dev = dev; 560 sc->node = ofw_bus_get_node(dev); 561 562 mtx_init(&sc->mtx, "pci_dw_mtx", NULL, MTX_DEF); 563 564 /* XXXn Should not be this configurable ? */ 565 sc->bus_start = 0; 566 sc->bus_end = 255; 567 sc->root_bus = 0; 568 sc->sub_bus = 1; 569 570 /* Read FDT properties */ 571 if (!sc->coherent) 572 sc->coherent = OF_hasprop(sc->node, "dma-coherent"); 573 574 rv = OF_getencprop(sc->node, "num-viewport", &sc->num_viewport, 575 sizeof(sc->num_viewport)); 576 if (rv != sizeof(sc->num_viewport)) 577 sc->num_viewport = 2; 578 579 rv = OF_getencprop(sc->node, "num-lanes", &sc->num_lanes, 580 sizeof(sc->num_viewport)); 581 if (rv != sizeof(sc->num_lanes)) 582 sc->num_lanes = 1; 583 if (sc->num_lanes != 1 && sc->num_lanes != 2 && 584 sc->num_lanes != 4 && sc->num_lanes != 8) { 585 device_printf(dev, 586 "invalid number of lanes: %d\n",sc->num_lanes); 587 sc->num_lanes = 0; 588 rv = ENXIO; 589 goto out; 590 } 591 592 rid = 0; 593 rv = ofw_bus_find_string_index(sc->node, "reg-names", "config", &rid); 594 if (rv != 0) { 595 device_printf(dev, "Cannot get config space memory\n"); 596 rv = ENXIO; 597 goto out; 598 } 599 sc->cfg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 600 RF_ACTIVE); 601 if (sc->cfg_res == NULL) { 602 device_printf(dev, "Cannot allocate config space(rid: %d)\n", 603 rid); 604 rv = ENXIO; 605 goto out; 606 } 607 608 /* Fill up config region related variables */ 609 sc->cfg_size = rman_get_size(sc->cfg_res); 610 sc->cfg_pa = rman_get_start(sc->cfg_res) ; 611 612 if (bootverbose) 613 device_printf(dev, "Bus is%s cache-coherent\n", 614 sc->coherent ? "" : " not"); 615 rv = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 616 1, 0, /* alignment, bounds */ 617 BUS_SPACE_MAXADDR, /* lowaddr */ 618 BUS_SPACE_MAXADDR, /* highaddr */ 619 NULL, NULL, /* filter, filterarg */ 620 BUS_SPACE_MAXSIZE, /* maxsize */ 621 BUS_SPACE_UNRESTRICTED, /* nsegments */ 622 BUS_SPACE_MAXSIZE, /* maxsegsize */ 623 sc->coherent ? BUS_DMA_COHERENT : 0, /* flags */ 624 NULL, NULL, /* lockfunc, lockarg */ 625 &sc->dmat); 626 if (rv != 0) 627 goto out; 628 629 rv = ofw_pci_init(dev); 630 if (rv != 0) 631 goto out; 632 rv = pci_dw_decode_ranges(sc, sc->ofw_pci.sc_range, 633 sc->ofw_pci.sc_nrange); 634 if (rv != 0) 635 goto out; 636 637 rv = pci_dw_setup_hw(sc); 638 if (rv != 0) 639 goto out; 640 641 device_add_child(dev, "pci", -1); 642 643 return (bus_generic_attach(dev)); 644 out: 645 /* XXX Cleanup */ 646 return (rv); 647 } 648 649 static device_method_t pci_dw_methods[] = { 650 /* Bus interface */ 651 DEVMETHOD(bus_get_dma_tag, pci_dw_get_dma_tag), 652 653 /* pcib interface */ 654 DEVMETHOD(pcib_read_config, pci_dw_read_config), 655 DEVMETHOD(pcib_write_config, pci_dw_write_config), 656 DEVMETHOD(pcib_alloc_msi, pci_dw_alloc_msi), 657 DEVMETHOD(pcib_release_msi, pci_dw_release_msi), 658 DEVMETHOD(pcib_alloc_msix, pci_dw_alloc_msix), 659 DEVMETHOD(pcib_release_msix, pci_dw_release_msix), 660 DEVMETHOD(pcib_map_msi, pci_dw_map_msi), 661 DEVMETHOD(pcib_get_id, pci_dw_get_id), 662 663 /* OFW bus interface */ 664 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), 665 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), 666 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), 667 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), 668 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), 669 670 /* PCI DW interface */ 671 DEVMETHOD(pci_dw_dbi_read, pci_dw_dbi_read), 672 DEVMETHOD(pci_dw_dbi_write, pci_dw_dbi_write), 673 DEVMETHOD_END 674 }; 675 676 DEFINE_CLASS_1(pcib, pci_dw_driver, pci_dw_methods, 677 sizeof(struct pci_dw_softc), ofw_pci_driver); 678