Index: sys/arm64/broadcom/iproc_pcie.c =================================================================== --- sys/arm64/broadcom/iproc_pcie.c +++ sys/arm64/broadcom/iproc_pcie.c @@ -134,11 +134,8 @@ * endpoint devices. */ enum iproc_pcie_type { - IPROC_PCIE_PAXB_BCMA = 0, - IPROC_PCIE_PAXB, - IPROC_PCIE_PAXB_V2, + IPROC_PCIE_PAXB = 0, IPROC_PCIE_PAXC, - IPROC_PCIE_PAXC_V2, }; /* @@ -221,18 +218,7 @@ uint16_t offset; }; -/* iProc PCIe PAXB BCMA registers */ -static const struct iproc_pcie_regs iproc_pcie_reg_paxb_bcma[] = { - {IPROC_PCIE_CLK_CTRL, 0x000}, - {IPROC_PCIE_CFG_IND_ADDR, 0x120}, - {IPROC_PCIE_CFG_IND_DATA, 0x124}, - {IPROC_PCIE_CFG_ADDR, 0x1f8}, - {IPROC_PCIE_CFG_DATA, 0x1fc}, - {IPROC_PCIE_INTX_EN, 0x330}, - {IPROC_PCIE_LINK_STATUS, 0xf0c}, -}; - -/* iProc PCIe PAXB registers */ +/* iProc PCIe PAXB v1 registers */ static const struct iproc_pcie_regs iproc_pcie_reg_paxb[] = { {IPROC_PCIE_CLK_CTRL, 0x000}, {IPROC_PCIE_CFG_IND_ADDR, 0x120}, @@ -248,34 +234,6 @@ {IPROC_PCIE_APB_ERR_EN, 0xf40}, }; -/* iProc PCIe PAXB v2 registers */ -static const struct iproc_pcie_regs iproc_pcie_reg_paxb_v2[] = { - {IPROC_PCIE_CLK_CTRL, 0x000}, - {IPROC_PCIE_CFG_IND_ADDR, 0x120}, - {IPROC_PCIE_CFG_IND_DATA, 0x124}, - {IPROC_PCIE_CFG_ADDR, 0x1f8}, - {IPROC_PCIE_CFG_DATA, 0x1fc}, - {IPROC_PCIE_INTX_EN, 0x330}, - {IPROC_PCIE_OARR0, 0xd20}, - {IPROC_PCIE_OMAP0, 0xd40}, - {IPROC_PCIE_OARR1, 0xd28}, - {IPROC_PCIE_OMAP1, 0xd48}, - {IPROC_PCIE_OARR2, 0xd60}, - {IPROC_PCIE_OMAP2, 0xd68}, - {IPROC_PCIE_OARR3, 0xdf0}, - {IPROC_PCIE_OMAP3, 0xdf8}, - {IPROC_PCIE_IARR0, 0xd00}, - {IPROC_PCIE_IMAP0, 0xc00}, - {IPROC_PCIE_IARR2, 0xd10}, - {IPROC_PCIE_IMAP2, 0xcc0}, - {IPROC_PCIE_IARR3, 0xe00}, - {IPROC_PCIE_IMAP3, 0xe08}, - {IPROC_PCIE_IARR4, 0xe68}, - {IPROC_PCIE_IMAP4, 0xe70}, - {IPROC_PCIE_LINK_STATUS, 0xf0c}, - {IPROC_PCIE_APB_ERR_EN, 0xf40}, -}; - /* iProc PCIe PAXC v1 registers */ static const struct iproc_pcie_regs iproc_pcie_reg_paxc[] = { {IPROC_PCIE_CLK_CTRL, 0x000}, @@ -285,20 +243,6 @@ {IPROC_PCIE_CFG_DATA, 0x1fc}, }; -/* iProc PCIe PAXC v2 registers */ -static const struct iproc_pcie_regs iproc_pcie_reg_paxc_v2[] = { - {IPROC_PCIE_MSI_GIC_MODE, 0x050}, - {IPROC_PCIE_MSI_BASE_ADDR, 0x074}, - {IPROC_PCIE_MSI_WINDOW_SIZE, 0x078}, - {IPROC_PCIE_MSI_ADDR_LO, 0x07c}, - {IPROC_PCIE_MSI_ADDR_HI, 0x080}, - {IPROC_PCIE_MSI_EN_CFG, 0x09c}, - {IPROC_PCIE_CFG_IND_ADDR, 0x1f0}, - {IPROC_PCIE_CFG_IND_DATA, 0x1f4}, - {IPROC_PCIE_CFG_ADDR, 0x1f8}, - {IPROC_PCIE_CFG_DATA, 0x1fc}, -}; - /* iProc PCIe outbound mapping info */ struct iproc_pcie_ob { /* offset from AXI address to the internal PCIe core address */ @@ -359,8 +303,6 @@ u_int func, u_int reg, uint32_t val, int bytes); static uint32_t iproc_pcie_read_config_internal(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, int bytes); -static void iproc_pcie_write_config_internal(device_t dev, u_int bus, - u_int slot, u_int func, u_int reg, uint32_t val, int bytes); static uint32_t iproc_pcie_generic_config_read(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, int bytes); @@ -383,8 +325,8 @@ static int iproc_pcie_rev_init(struct iproc_pcie_softc *sc); static uint32_t iproc_pcie_cfg_retry(struct iproc_pcie_softc *sc, uint16_t offset); -static void iproc_pcie_apb_err_disable(struct iproc_pcie_softc *sc, u_int bus, - int disable); +static void iproc_pcie_apb_err_enable(struct iproc_pcie_softc *sc, u_int bus); +static void iproc_pcie_apb_err_disable(struct iproc_pcie_softc *sc, u_int bus); static void iproc_pcie_intx_enable(struct iproc_pcie_softc *sc); static int iproc_pcie_ob_write(struct iproc_pcie_softc *sc, int window, int size_idx, uint64_t axi_addr, uint64_t pci_addr); @@ -402,15 +344,6 @@ /* Bus interface */ DEVMETHOD(bus_get_dma_tag, iproc_pcie_get_dma_tag), - DEVMETHOD(bus_read_ivar, ofw_pci_read_ivar), - DEVMETHOD(bus_write_ivar, ofw_pci_write_ivar), - DEVMETHOD(bus_alloc_resource, ofw_pci_alloc_resource), - DEVMETHOD(bus_release_resource, ofw_pci_release_resource), - DEVMETHOD(bus_activate_resource, ofw_pci_activate_resource), - DEVMETHOD(bus_deactivate_resource, ofw_pci_deactivate_resource), - DEVMETHOD(bus_adjust_resource, ofw_pci_adjust_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), /* pcib interface */ DEVMETHOD(pcib_route_interrupt, iproc_pcie_route_interrupt), @@ -426,24 +359,20 @@ DEVMETHOD_END }; -static driver_t iproc_pcie_driver = { - "pcib", - iproc_pcie_methods, - sizeof(struct iproc_pcie_softc), -}; - static devclass_t iproc_pcie_devclass; +DEFINE_CLASS_1(pcib, iproc_pcie_driver, iproc_pcie_methods, + sizeof(struct iproc_pcie_softc), ofw_pci_driver); + DRIVER_MODULE(iproc_pcie, simplebus, iproc_pcie_driver, iproc_pcie_devclass, 0, 0); DRIVER_MODULE(iproc_pcie, ofwbus, iproc_pcie_driver, iproc_pcie_devclass, 0, 0); + MODULE_DEPEND(iproc_pcie, pci, 1, 1, 1); static struct ofw_compat_data compat_data[] = { {"brcm,iproc-pcie", (uintptr_t)IPROC_PCIE_PAXB}, - {"brcm,iproc-pcie-paxb-v2", (uintptr_t)IPROC_PCIE_PAXB_V2}, {"brcm,iproc-pcie-paxc", (uintptr_t)IPROC_PCIE_PAXC}, {"brcm,iproc-pcie-nitro", (uintptr_t)IPROC_PCIE_PAXC}, - {"brcm,iproc-pcie-paxc-v2", (uintptr_t)IPROC_PCIE_PAXC_V2}, {NULL, 0} }; @@ -546,7 +475,8 @@ rv = iproc_pcie_check_link(sc); if (rv != 0) { - device_printf(dev, "no PCIe EP device detected\n"); + if (bootverbose) + device_printf(dev, "no PCIe EP device detected\n"); return (ENXIO); } @@ -662,8 +592,7 @@ sc = device_get_softc(bus); /* PAXC doesn't support legacy IRQs, skip mapping */ - if (sc->type == IPROC_PCIE_PAXC || - sc->type == IPROC_PCIE_PAXC_V2) + if (sc->type == IPROC_PCIE_PAXC) return (PCI_INVALID_IRQ); return (ofw_pci_route_interrupt(bus, dev, pin)); @@ -673,7 +602,7 @@ iproc_pcie_reg_invalid(uint16_t reg_offset) { - return (!!(reg_offset == IPROC_PCIE_REG_INVALID)); + return (reg_offset == IPROC_PCIE_REG_INVALID); } static uint16_t @@ -800,7 +729,7 @@ if (slot > 0) return (~0U); - iproc_pcie_apb_err_disable(sc, bus, 1); + iproc_pcie_apb_err_disable(sc, bus); if (sc->iproc_cfg_read) val = iproc_pcie_read_config_internal(dev, bus, slot, @@ -809,7 +738,7 @@ val = iproc_pcie_generic_config_read(dev, bus, slot, func, reg, bytes); - iproc_pcie_apb_err_disable(sc, bus, 0); + iproc_pcie_apb_err_enable(sc, bus); /* quirks */ if (sc->ep_is_internal) { @@ -875,39 +804,26 @@ u_int func, u_int reg, uint32_t val, int bytes) { struct iproc_pcie_softc *sc; - - sc = device_get_softc(dev); - - iproc_pcie_apb_err_disable(sc, bus, 1); - - iproc_pcie_write_config_internal(dev, bus, slot, - func, reg, val, bytes); - - iproc_pcie_apb_err_disable(sc, bus, 0); -} -static void -iproc_pcie_write_config_internal(device_t dev, u_int bus, u_int slot, - u_int func, u_int reg, uint32_t val, int bytes) -{ - struct iproc_pcie_softc *sc; uint32_t mask, tmp; uint16_t offset; int rv; + sc = device_get_softc(dev); + if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX)) return; - sc = device_get_softc(dev); + iproc_pcie_apb_err_disable(sc, bus); rv = iproc_pcie_map_cfg_bus(sc, bus, slot, func, reg & ~0x3, &offset); if (rv != 0) - return; + goto out; if (bytes == 4) { bus_write_4(sc->reg, offset, val); bus_barrier(sc->reg, offset, 4, BUS_SPACE_BARRIER_WRITE); - return; + goto out; } mask = ~(((1 << (bytes * 8)) - 1) << ((reg & 0x3) * 8)); @@ -916,6 +832,9 @@ bus_write_4(sc->reg, offset, tmp); bus_barrier(sc->reg, offset, 4, BUS_SPACE_BARRIER_WRITE); + +out: + iproc_pcie_apb_err_enable(sc, bus); } static uint32_t @@ -965,7 +884,7 @@ * triggering a system exception. */ static void -iproc_pcie_apb_err_disable(struct iproc_pcie_softc *sc, u_int bus, int disable) +iproc_pcie_apb_err_disable(struct iproc_pcie_softc *sc, u_int bus) { uint32_t val; int rv; @@ -975,10 +894,23 @@ if (rv != 0) return; - if (disable) - val &= ~APB_ERR_EN; - else - val |= APB_ERR_EN; + val &= ~APB_ERR_EN; + rv = iproc_pcie_write_reg(sc, IPROC_PCIE_APB_ERR_EN, val); + } +} + +static void +iproc_pcie_apb_err_enable(struct iproc_pcie_softc *sc, u_int bus) +{ + uint32_t val; + int rv; + + if (bus && sc->has_apb_err_disable) { + rv = iproc_pcie_read_reg(sc, IPROC_PCIE_APB_ERR_EN, &val); + if (rv != 0) + return; + + val |= APB_ERR_EN; rv = iproc_pcie_write_reg(sc, IPROC_PCIE_APB_ERR_EN, val); } } @@ -1022,11 +954,6 @@ { switch (sc->type) { - case IPROC_PCIE_PAXB_BCMA: - sc->reg_offsets = iproc_pcie_reg_paxb_bcma; - sc->num_regs = nitems(iproc_pcie_reg_paxb_bcma); - device_printf(sc->dev, "unsupported iProc PCIe interface\n"); - return (ENXIO); case IPROC_PCIE_PAXB: sc->reg_offsets = iproc_pcie_reg_paxb; sc->num_regs = nitems(iproc_pcie_reg_paxb); @@ -1037,24 +964,14 @@ sc->ob.nr_windows = nitems(paxb_ob_map); } break; - case IPROC_PCIE_PAXB_V2: - sc->reg_offsets = iproc_pcie_reg_paxb_v2; - sc->num_regs = nitems(iproc_pcie_reg_paxb_v2); - device_printf(sc->dev, "unsupported iProc PCIe interface\n"); - return (ENXIO); case IPROC_PCIE_PAXC: sc->reg_offsets = iproc_pcie_reg_paxc; sc->num_regs = nitems(iproc_pcie_reg_paxc); sc->ep_is_internal = 1; sc->iproc_cfg_read = 1; break; - case IPROC_PCIE_PAXC_V2: - sc->reg_offsets = iproc_pcie_reg_paxc_v2; - sc->num_regs = nitems(iproc_pcie_reg_paxc_v2); - device_printf(sc->dev, "unsupported iProc PCIe interface\n"); - return (ENXIO); default: - device_printf(sc->dev, "incompatible iProc PCIe interface\n"); + device_printf(sc->dev, "unsupported iProc PCIe interface\n"); return (ENXIO); }