From 1f1d8cd1f54354750bcaf95adbd287e250187aa5 Mon Sep 17 00:00:00 2001 From: jhibbits Date: Sun, 22 Nov 2015 01:16:43 +0000 Subject: Modernize mpc85xx PCI hostbridge driver. Summary: * Take advantage of NEW_PCIB to remove a lot of setup code. * Fix some bugs related to multiple PCI bridges. There's still room for more cleanup, and still some bugs leftover, but this cleans up a lot. Test Plan: Tested on P5020 board with IDT PCIe switch. Differential Revision: https://reviews.freebsd.org/D4127 --- sys/powerpc/mpc85xx/pci_mpc85xx.c | 125 ++------------------------------- sys/powerpc/mpc85xx/pci_mpc85xx_pcib.c | 21 +----- 2 files changed, 8 insertions(+), 138 deletions(-) (limited to 'sys/powerpc/mpc85xx') diff --git a/sys/powerpc/mpc85xx/pci_mpc85xx.c b/sys/powerpc/mpc85xx/pci_mpc85xx.c index 70bdb72..6dbdf09 100644 --- a/sys/powerpc/mpc85xx/pci_mpc85xx.c +++ b/sys/powerpc/mpc85xx/pci_mpc85xx.c @@ -104,9 +104,9 @@ struct fsl_pcib_softc { device_t sc_dev; int sc_iomem_target; - bus_addr_t sc_iomem_alloc, sc_iomem_start, sc_iomem_end; + bus_addr_t sc_iomem_start, sc_iomem_end; int sc_ioport_target; - bus_addr_t sc_ioport_alloc, sc_ioport_start, sc_ioport_end; + bus_addr_t sc_ioport_start, sc_ioport_end; struct resource *sc_res; bus_space_handle_t sc_bsh; @@ -266,9 +266,8 @@ fsl_pcib_attach(device_t dev) /* * Scan bus using firmware configured, 0 based bus numbering. */ - sc->sc_busnr = 0; maxslot = (sc->sc_pcie) ? 0 : PCI_SLOTMAX; - sc->sc_busnr = fsl_pcib_init(sc, sc->sc_busnr, maxslot); + fsl_pcib_init(sc, sc->sc_busnr, maxslot); if (sc->sc_pcie) { ltssm = fsl_pcib_cfgread(sc, 0, 0, 0, PCIR_LTSSM, 1); @@ -285,6 +284,7 @@ fsl_pcib_attach(device_t dev) return (ofw_pci_attach(dev)); err: + //panic("Because I said so\n"); return (ENXIO); } @@ -294,9 +294,6 @@ fsl_pcib_cfgread(struct fsl_pcib_softc *sc, u_int bus, u_int slot, u_int func, { uint32_t addr, data; - if (bus == sc->sc_busnr - 1) - bus = 0; - addr = CONFIG_ACCESS_ENABLE; addr |= (bus & 0xff) << 16; addr |= (slot & 0x1f) << 11; @@ -335,9 +332,6 @@ fsl_pcib_cfgwrite(struct fsl_pcib_softc *sc, u_int bus, u_int slot, u_int func, { uint32_t addr; - if (bus == sc->sc_busnr - 1) - bus = 0; - addr = CONFIG_ACCESS_ENABLE; addr |= (bus & 0xff) << 16; addr |= (slot & 0x1f) << 11; @@ -449,74 +443,14 @@ fsl_pcib_init_via(struct fsl_pcib_softc *sc, uint16_t device, int bus, } static int -fsl_pcib_init_bar(struct fsl_pcib_softc *sc, int bus, int slot, int func, - int barno) -{ - bus_addr_t *allocp; - uint32_t addr, mask, size; - int reg, width; - - reg = PCIR_BAR(barno); - - if (DEVFN(bus, slot, func) == sc->sc_devfn_via_ide) { - switch (barno) { - case 0: addr = 0x1f0; break; - case 1: addr = 0x3f4; break; - case 2: addr = 0x170; break; - case 3: addr = 0x374; break; - case 4: addr = 0xcc0; break; - default: return (1); - } - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); - return (1); - } - - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4); - size = fsl_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4); - if (size == 0) - return (1); - width = ((size & 7) == 4) ? 2 : 1; - - if (size & 1) { /* I/O port */ - allocp = &sc->sc_ioport_alloc; - size &= ~3; - if ((size & 0xffff0000) == 0) - size |= 0xffff0000; - } else { /* memory */ - allocp = &sc->sc_iomem_alloc; - size &= ~15; - } - mask = ~size; - size = mask + 1; - /* Sanity check (must be a power of 2). */ - if (size & mask) - return (width); - - addr = (*allocp + mask) & ~mask; - *allocp = addr + size; - - if (bootverbose) - printf("PCI %u:%u:%u:%u: reg %x: size=%08x: addr=%08x\n", - device_get_unit(sc->sc_dev), bus, slot, func, reg, - size, addr); - - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); - if (width == 2) - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, reg + 4, - 0, 4); - return (width); -} - -static int fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int maxslot) { int secbus; int old_pribus, old_secbus, old_subbus; int new_pribus, new_secbus, new_subbus; int slot, func, maxfunc; - int bar, maxbar; uint16_t vendor, device; - uint8_t command, hdrtype, class, subclass; + uint8_t command, hdrtype, subclass; secbus = bus; for (slot = 0; slot <= maxslot; slot++) { @@ -550,26 +484,9 @@ fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int maxslot) if (vendor == 0x1106) fsl_pcib_init_via(sc, device, bus, slot, func); - /* Program the base address registers. */ - maxbar = (hdrtype & PCIM_HDRTYPE) ? 1 : 6; - bar = 0; - while (bar < maxbar) - bar += fsl_pcib_init_bar(sc, bus, slot, func, - bar); - - /* Put a placeholder interrupt value */ - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_INTLINE, PCI_INVALID_IRQ, 1); - - command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN; - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_COMMAND, command, 1); - /* * Handle PCI-PCI bridges */ - class = fsl_pcib_read_config(sc->sc_dev, bus, slot, - func, PCIR_CLASS, 1); subclass = fsl_pcib_read_config(sc->sc_dev, bus, slot, func, PCIR_SUBCLASS, 1); @@ -579,32 +496,6 @@ fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int maxslot) secbus++; - /* Program I/O decoder. */ - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_IOBASEL_1, sc->sc_ioport_start >> 8, 1); - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_IOLIMITL_1, sc->sc_ioport_end >> 8, 1); - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_IOBASEH_1, sc->sc_ioport_start >> 16, 2); - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_IOLIMITH_1, sc->sc_ioport_end >> 16, 2); - - /* Program (non-prefetchable) memory decoder. */ - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_MEMBASE_1, sc->sc_iomem_start >> 16, 2); - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_MEMLIMIT_1, sc->sc_iomem_end >> 16, 2); - - /* Program prefetchable memory decoder. */ - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_PMBASEL_1, 0x0010, 2); - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_PMLIMITL_1, 0x000f, 2); - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_PMBASEH_1, 0x00000000, 4); - fsl_pcib_write_config(sc->sc_dev, bus, slot, func, - PCIR_PMLIMITH_1, 0x00000000, 4); - /* Read currect bus register configuration */ old_pribus = fsl_pcib_read_config(sc->sc_dev, bus, slot, func, PCIR_PRIBUS_1, 1); @@ -678,10 +569,10 @@ fsl_pcib_outbound(struct fsl_pcib_softc *sc, int wnd, int res, uint64_t start, switch (res) { case SYS_RES_MEMORY: - attr = 0x80044000 | (ffsl(size) - 2); + attr = 0x80044000 | (ffsll(size) - 2); break; case SYS_RES_IOPORT: - attr = 0x80088000 | (ffsl(size) - 2); + attr = 0x80088000 | (ffsll(size) - 2); break; default: attr = 0x0004401f; @@ -785,7 +676,6 @@ fsl_pcib_decode_win(phandle_t node, struct fsl_pcib_softc *sc) sc->sc_ioport_start = sc->pci_sc.sc_range[i].pci; sc->sc_ioport_end = sc->pci_sc.sc_range[i].pci + sc->pci_sc.sc_range[i].size - 1; - sc->sc_ioport_alloc = 0x1000 + sc->pci_sc.sc_range[i].pci; break; case OFW_PCI_PHYS_HI_SPACE_MEM32: case OFW_PCI_PHYS_HI_SPACE_MEM64: @@ -797,7 +687,6 @@ fsl_pcib_decode_win(phandle_t node, struct fsl_pcib_softc *sc) sc->sc_iomem_start = sc->pci_sc.sc_range[i].pci; sc->sc_iomem_end = sc->pci_sc.sc_range[i].pci + sc->pci_sc.sc_range[i].size - 1; - sc->sc_iomem_alloc = sc->pci_sc.sc_range[i].pci; break; default: panic("Unknown range type %#x\n", diff --git a/sys/powerpc/mpc85xx/pci_mpc85xx_pcib.c b/sys/powerpc/mpc85xx/pci_mpc85xx_pcib.c index a8f0325..397d5e8 100644 --- a/sys/powerpc/mpc85xx/pci_mpc85xx_pcib.c +++ b/sys/powerpc/mpc85xx/pci_mpc85xx_pcib.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); static int fsl_pcib_rc_probe(device_t dev) { + if (pci_get_vendor(dev) != 0x1957) return (ENXIO); if (pci_get_progif(dev) != 0) @@ -71,28 +72,8 @@ fsl_pcib_rc_probe(device_t dev) return (BUS_PROBE_DEFAULT); } -static int -fsl_pcib_rc_attach(device_t dev) -{ - struct pcib_softc *sc; - device_t child; - - pcib_bridge_init(dev); - pcib_attach_common(dev); - - sc = device_get_softc(dev); - if (sc->bus.sec != 0) { - child = device_add_child(dev, "pci", -1); - if (child != NULL) - return (bus_generic_attach(dev)); - } - - return (0); -} - static device_method_t fsl_pcib_rc_methods[] = { DEVMETHOD(device_probe, fsl_pcib_rc_probe), - DEVMETHOD(device_attach, fsl_pcib_rc_attach), DEVMETHOD_END }; -- cgit v1.1