pci_host_generic.c (284319) | pci_host_generic.c (292215) |
---|---|
1/*- 2 * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> 3 * Copyright (c) 2014 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * This software was developed by Semihalf under 7 * the sponsorship of the FreeBSD Foundation. 8 * --- 17 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31/* Generic ECAM PCIe driver */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> 3 * Copyright (c) 2014 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * This software was developed by Semihalf under 7 * the sponsorship of the FreeBSD Foundation. 8 * --- 17 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31/* Generic ECAM PCIe driver */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/pci/pci_host_generic.c 284319 2015-06-12 13:54:25Z br $"); | 34__FBSDID("$FreeBSD: head/sys/dev/pci/pci_host_generic.c 292215 2015-12-14 17:08:40Z andrew $"); |
35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/malloc.h> 39#include <sys/kernel.h> 40#include <sys/rman.h> 41#include <sys/module.h> 42#include <sys/bus.h> 43#include <sys/endian.h> 44#include <sys/cpuset.h> 45#include <sys/rwlock.h> | 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/malloc.h> 39#include <sys/kernel.h> 40#include <sys/rman.h> 41#include <sys/module.h> 42#include <sys/bus.h> 43#include <sys/endian.h> 44#include <sys/cpuset.h> 45#include <sys/rwlock.h> |
46 |
|
46#include <dev/ofw/openfirm.h> 47#include <dev/ofw/ofw_bus.h> 48#include <dev/ofw/ofw_bus_subr.h> | 47#include <dev/ofw/openfirm.h> 48#include <dev/ofw/ofw_bus.h> 49#include <dev/ofw/ofw_bus_subr.h> |
50#include <dev/ofw/ofw_pci.h> |
|
49#include <dev/pci/pcivar.h> 50#include <dev/pci/pcireg.h> 51#include <dev/pci/pcib_private.h> | 51#include <dev/pci/pcivar.h> 52#include <dev/pci/pcireg.h> 53#include <dev/pci/pcib_private.h> |
54 |
|
52#include <machine/cpu.h> 53#include <machine/bus.h> 54#include <machine/intr.h> 55#include <vm/vm_page.h> 56 57#include "pcib_if.h" 58 59/* Assembling ECAM Configuration Address */ --- 10 unchanged lines hidden (view full) --- 70 (((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT) | \ 71 (((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT) | \ 72 ((reg) & PCIE_REG_MASK)) 73 74#define MAX_RANGES_TUPLES 5 75#define MIN_RANGES_TUPLES 2 76 77#define PCI_IO_WINDOW_OFFSET 0x1000 | 55#include <machine/cpu.h> 56#include <machine/bus.h> 57#include <machine/intr.h> 58#include <vm/vm_page.h> 59 60#include "pcib_if.h" 61 62/* Assembling ECAM Configuration Address */ --- 10 unchanged lines hidden (view full) --- 73 (((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT) | \ 74 (((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT) | \ 75 ((reg) & PCIE_REG_MASK)) 76 77#define MAX_RANGES_TUPLES 5 78#define MIN_RANGES_TUPLES 2 79 80#define PCI_IO_WINDOW_OFFSET 0x1000 |
78#define PCI_IRQ_START 32 79#define PCI_IRQ_END (PCI_IRQ_START + 4) | |
80 81#define SPACE_CODE_SHIFT 24 82#define SPACE_CODE_MASK 0x3 83#define SPACE_CODE_IO_SPACE 0x1 84#define PROPS_CELL_SIZE 1 85#define PCI_ADDR_CELL_SIZE 2 86 87struct pcie_range { --- 5 unchanged lines hidden (view full) --- 93#define FLAG_MEM (1 << 1) 94}; 95 96struct generic_pcie_softc { 97 struct pcie_range ranges[MAX_RANGES_TUPLES]; 98 int nranges; 99 struct rman mem_rman; 100 struct rman io_rman; | 81 82#define SPACE_CODE_SHIFT 24 83#define SPACE_CODE_MASK 0x3 84#define SPACE_CODE_IO_SPACE 0x1 85#define PROPS_CELL_SIZE 1 86#define PCI_ADDR_CELL_SIZE 2 87 88struct pcie_range { --- 5 unchanged lines hidden (view full) --- 94#define FLAG_MEM (1 << 1) 95}; 96 97struct generic_pcie_softc { 98 struct pcie_range ranges[MAX_RANGES_TUPLES]; 99 int nranges; 100 struct rman mem_rman; 101 struct rman io_rman; |
101 struct rman irq_rman; | |
102 struct resource *res; 103 struct resource *res1; 104 int ecam; 105 bus_space_tag_t bst; 106 bus_space_handle_t bsh; 107 device_t dev; 108 bus_space_handle_t ioh; | 102 struct resource *res; 103 struct resource *res1; 104 int ecam; 105 bus_space_tag_t bst; 106 bus_space_handle_t bsh; 107 device_t dev; 108 bus_space_handle_t ioh; |
109 struct ofw_bus_iinfo pci_iinfo; |
|
109}; 110 111/* Forward prototypes */ 112 113static int generic_pcie_probe(device_t dev); 114static int generic_pcie_attach(device_t dev); 115static int parse_pci_mem_ranges(struct generic_pcie_softc *sc); 116static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot, --- 94 unchanged lines hidden (view full) --- 211 if (error) { 212 device_printf(dev, "rman_manage_region() failed." 213 "error = %d\n", error); 214 rman_fini(&sc->mem_rman); 215 return (error); 216 } 217 } 218 | 110}; 111 112/* Forward prototypes */ 113 114static int generic_pcie_probe(device_t dev); 115static int generic_pcie_attach(device_t dev); 116static int parse_pci_mem_ranges(struct generic_pcie_softc *sc); 117static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot, --- 94 unchanged lines hidden (view full) --- 212 if (error) { 213 device_printf(dev, "rman_manage_region() failed." 214 "error = %d\n", error); 215 rman_fini(&sc->mem_rman); 216 return (error); 217 } 218 } 219 |
219 /* TODO: get IRQ numbers from FDT */ 220 sc->irq_rman.rm_type = RMAN_ARRAY; 221 sc->irq_rman.rm_descr = "Generic PCIe IRQs"; 222 if (rman_init(&sc->irq_rman) != 0 || 223 rman_manage_region(&sc->irq_rman, PCI_IRQ_START, 224 PCI_IRQ_END) != 0) { 225 panic("Generic PCI: failed to set up IRQ rman"); 226 } | 220 ofw_bus_setup_iinfo(ofw_bus_get_node(dev), &sc->pci_iinfo, 221 sizeof(cell_t)); |
227 | 222 |
223 |
|
228 device_add_child(dev, "pci", -1); 229 return (bus_generic_attach(dev)); 230} 231 232static int 233parse_pci_mem_ranges(struct generic_pcie_softc *sc) 234{ 235 pcell_t pci_addr_cells, parent_addr_cells; --- 100 unchanged lines hidden (view full) --- 336 break; 337 case 4: 338 data = le32toh(bus_space_read_4(t, h, offset)); 339 break; 340 default: 341 return (~0U); 342 } 343 | 224 device_add_child(dev, "pci", -1); 225 return (bus_generic_attach(dev)); 226} 227 228static int 229parse_pci_mem_ranges(struct generic_pcie_softc *sc) 230{ 231 pcell_t pci_addr_cells, parent_addr_cells; --- 100 unchanged lines hidden (view full) --- 332 break; 333 case 4: 334 data = le32toh(bus_space_read_4(t, h, offset)); 335 break; 336 default: 337 return (~0U); 338 } 339 |
344 if (reg == PCIR_INTLINE) { 345 data += PCI_IRQ_START; 346 } 347 | |
348 return (data); 349} 350 351static void 352generic_pcie_write_config(device_t dev, u_int bus, u_int slot, 353 u_int func, u_int reg, uint32_t val, int bytes) 354{ 355 struct generic_pcie_softc *sc; --- 29 unchanged lines hidden (view full) --- 385static int 386generic_pcie_maxslots(device_t dev) 387{ 388 389 return (31); /* max slots per bus acc. to standard */ 390} 391 392static int | 340 return (data); 341} 342 343static void 344generic_pcie_write_config(device_t dev, u_int bus, u_int slot, 345 u_int func, u_int reg, uint32_t val, int bytes) 346{ 347 struct generic_pcie_softc *sc; --- 29 unchanged lines hidden (view full) --- 377static int 378generic_pcie_maxslots(device_t dev) 379{ 380 381 return (31); /* max slots per bus acc. to standard */ 382} 383 384static int |
385generic_pcie_route_interrupt(device_t bus, device_t dev, int pin) 386{ 387 struct generic_pcie_softc *sc; 388 struct ofw_pci_register reg; 389 uint32_t pintr, mintr[2]; 390 phandle_t iparent; 391 int intrcells; 392 393 sc = device_get_softc(bus); 394 pintr = pin; 395 396 bzero(®, sizeof(reg)); 397 reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) | 398 (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) | 399 (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT); 400 401 intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev), 402 &sc->pci_iinfo, ®, sizeof(reg), &pintr, sizeof(pintr), 403 mintr, sizeof(mintr), &iparent); 404 if (intrcells) { 405 pintr = ofw_bus_map_intr(dev, iparent, intrcells, mintr); 406 return (pintr); 407 } 408 409 device_printf(bus, "could not route pin %d for device %d.%d\n", 410 pin, pci_get_slot(dev), pci_get_function(dev)); 411 return (PCI_INVALID_IRQ); 412} 413 414 415static int |
|
393generic_pcie_read_ivar(device_t dev, device_t child, int index, 394 uintptr_t *result) 395{ 396 struct generic_pcie_softc *sc; 397 int secondary_bus; 398 399 sc = device_get_softc(dev); 400 --- 26 unchanged lines hidden (view full) --- 427generic_pcie_rman(struct generic_pcie_softc *sc, int type) 428{ 429 430 switch (type) { 431 case SYS_RES_IOPORT: 432 return (&sc->io_rman); 433 case SYS_RES_MEMORY: 434 return (&sc->mem_rman); | 416generic_pcie_read_ivar(device_t dev, device_t child, int index, 417 uintptr_t *result) 418{ 419 struct generic_pcie_softc *sc; 420 int secondary_bus; 421 422 sc = device_get_softc(dev); 423 --- 26 unchanged lines hidden (view full) --- 450generic_pcie_rman(struct generic_pcie_softc *sc, int type) 451{ 452 453 switch (type) { 454 case SYS_RES_IOPORT: 455 return (&sc->io_rman); 456 case SYS_RES_MEMORY: 457 return (&sc->mem_rman); |
435 case SYS_RES_IRQ: 436 return (&sc->irq_rman); | |
437 default: 438 break; 439 } 440 441 return (NULL); 442} 443 444static int --- 156 unchanged lines hidden (view full) --- 601 DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar), 602 DEVMETHOD(bus_alloc_resource, generic_pcie_alloc_resource), 603 DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource), 604 DEVMETHOD(bus_release_resource, generic_pcie_release_resource), 605 DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource), 606 DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource), 607 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 608 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), | 458 default: 459 break; 460 } 461 462 return (NULL); 463} 464 465static int --- 156 unchanged lines hidden (view full) --- 622 DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar), 623 DEVMETHOD(bus_alloc_resource, generic_pcie_alloc_resource), 624 DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource), 625 DEVMETHOD(bus_release_resource, generic_pcie_release_resource), 626 DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource), 627 DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource), 628 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 629 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), |
630 631 /* pcib interface */ |
|
609 DEVMETHOD(pcib_maxslots, generic_pcie_maxslots), | 632 DEVMETHOD(pcib_maxslots, generic_pcie_maxslots), |
633 DEVMETHOD(pcib_route_interrupt, generic_pcie_route_interrupt), |
|
610 DEVMETHOD(pcib_read_config, generic_pcie_read_config), 611 DEVMETHOD(pcib_write_config, generic_pcie_write_config), | 634 DEVMETHOD(pcib_read_config, generic_pcie_read_config), 635 DEVMETHOD(pcib_write_config, generic_pcie_write_config), |
636#if defined(__aarch64__) 637 DEVMETHOD(pcib_alloc_msi, arm_alloc_msi), 638 DEVMETHOD(pcib_release_msi, arm_release_msi), 639 DEVMETHOD(pcib_alloc_msix, arm_alloc_msix), 640 DEVMETHOD(pcib_release_msix, arm_release_msix), 641 DEVMETHOD(pcib_map_msi, arm_map_msi), 642#endif 643 |
|
612 DEVMETHOD_END 613}; 614 615static driver_t generic_pcie_driver = { 616 "pcib", 617 generic_pcie_methods, 618 sizeof(struct generic_pcie_softc), 619}; 620 621static devclass_t generic_pcie_devclass; 622 623DRIVER_MODULE(pcib, simplebus, generic_pcie_driver, 624generic_pcie_devclass, 0, 0); 625DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver, 626generic_pcie_devclass, 0, 0); | 644 DEVMETHOD_END 645}; 646 647static driver_t generic_pcie_driver = { 648 "pcib", 649 generic_pcie_methods, 650 sizeof(struct generic_pcie_softc), 651}; 652 653static devclass_t generic_pcie_devclass; 654 655DRIVER_MODULE(pcib, simplebus, generic_pcie_driver, 656generic_pcie_devclass, 0, 0); 657DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver, 658generic_pcie_devclass, 0, 0); |