From a32b54357f2b915718c7d179537be19ea2ebd622 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Tue, 31 Oct 2017 02:53:50 +0000 Subject: [PATCH] Make DPAA work in 64-bit mode Rework the dTSEC and FMan drivers to be more like a full bus relationship, so that dtsec can use bus_alloc_resource() instead of trying to handle the offset from the dts. This required taking some code from the sparc64 ebus driver to allow subdividing the fman region for the dTSEC devices. --- .../ncsw/Peripherals/FM/Port/fm_port.c | 2 +- .../ncsw/Peripherals/QM/qm_portal_fqr.c | 6 +- sys/contrib/ncsw/etc/memcpy.c | 4 +- sys/dev/dpaa/fman.c | 184 +++++++++++++++++- sys/dev/dpaa/fman.h | 7 + sys/dev/dpaa/fman_fdt.c | 3 + sys/dev/dpaa/if_dtsec.c | 2 +- sys/dev/dpaa/if_dtsec.h | 1 + sys/dev/dpaa/if_dtsec_fdt.c | 9 +- sys/dev/dpaa/if_dtsec_rm.c | 10 +- sys/powerpc/conf/QORIQ64 | 2 + 11 files changed, 213 insertions(+), 17 deletions(-) diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c index e277b425068..79419eab453 100644 --- a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c +++ b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c @@ -1996,7 +1996,7 @@ t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_CcParams) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; - int tmpInt; + uint32_t tmpInt; volatile uint32_t *p_BmiPrsStartOffset = NULL; /* this function called from Cc for pass and receive parameters port params between CC and PORT*/ diff --git a/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c b/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c index f49c1f42258..605d09aeb1a 100644 --- a/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c +++ b/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c @@ -78,8 +78,7 @@ aligned_int_from_ptr(const void *p) KASSERT(ctx >= VM_MIN_KERNEL_ADDRESS, ("%p is too low!\n", p)); ctx -= VM_MIN_KERNEL_ADDRESS; KASSERT((ctx & 0x07) == 0, ("Pointer %p is not 8-byte aligned!\n", p)); - if ((ctx & (0x7)) != 0) - return (0); + return (ctx >> 3); } @@ -88,7 +87,8 @@ ptr_from_aligned_int(uint32_t ctx) { uintptr_t p; - p = VM_MIN_KERNEL_ADDRESS + (ctx << 3); + p = ctx; + p = VM_MIN_KERNEL_ADDRESS + (p << 3); return ((void *)p); } diff --git a/sys/contrib/ncsw/etc/memcpy.c b/sys/contrib/ncsw/etc/memcpy.c index fa203ec7ceb..8494440bd1c 100644 --- a/sys/contrib/ncsw/etc/memcpy.c +++ b/sys/contrib/ncsw/etc/memcpy.c @@ -38,7 +38,7 @@ void * MemCpy8(void* pDst, void* pSrc, uint32_t size) { - int i; + uint32_t i; for(i = 0; i < size; ++i) *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i); @@ -48,7 +48,7 @@ void * MemCpy8(void* pDst, void* pSrc, uint32_t size) void * MemSet8(void* pDst, int c, uint32_t size) { - int i; + uint32_t i; for(i = 0; i < size; ++i) *(((uint8_t*)(pDst)) + i) = (uint8_t)(c); diff --git a/sys/dev/dpaa/fman.c b/sys/dev/dpaa/fman.c index 2312a85c48f..838247774b1 100644 --- a/sys/dev/dpaa/fman.c +++ b/sys/dev/dpaa/fman.c @@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include "opt_platform.h" #include @@ -87,10 +89,184 @@ const uint32_t fman_firmware[] = FMAN_UC_IMG; const uint32_t fman_firmware_size = sizeof(fman_firmware); static struct fman_softc *fm_sc = NULL; +int +fman_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + struct fman_softc *sc; + bus_space_tag_t bt; + bus_space_handle_t bh; + int i, rv; + + sc = device_get_softc(bus); + if (type != SYS_RES_IRQ) { + for (i = 0; i < sc->sc_base.nranges; i++) { + if (rman_is_region_manager(res, &sc->rman) != 0) { + bt = rman_get_bustag(sc->mem_res); + rv = bus_space_subregion(bt, + rman_get_bushandle(sc->mem_res), + rman_get_start(res) - + rman_get_start(sc->mem_res), + rman_get_size(res), &bh); + if (rv != 0) + return (rv); + rman_set_bustag(res, bt); + rman_set_bushandle(res, bh); + return (rman_activate_resource(res)); + } + } + return (EINVAL); + } + return (bus_generic_activate_resource(bus, child, type, rid, res)); +} + +int +fman_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + struct fman_softc *sc; + struct resource_list *rl; + struct resource_list_entry *rle; + int passthrough, rv; + + passthrough = (device_get_parent(child) != bus); + rl = BUS_GET_RESOURCE_LIST(bus, child); + sc = device_get_softc(bus); + if (type != SYS_RES_IRQ) { + if ((rman_get_flags(res) & RF_ACTIVE) != 0 ){ + rv = bus_deactivate_resource(child, type, rid, res); + if (rv != 0) + return (rv); + } + rv = rman_release_resource(res); + if (rv != 0) + return (rv); + if (!passthrough) { + rle = resource_list_find(rl, type, rid); + KASSERT(rle != NULL, + ("%s: resource entry not found!", __func__)); + KASSERT(rle->res != NULL, + ("%s: resource entry is not busy", __func__)); + rle->res = NULL; + } + return (0); + } + return (resource_list_release(rl, bus, child, type, rid, res)); +} + +struct resource * +fman_alloc_resource(device_t bus, device_t child, int type, int *rid, + rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) +{ + struct fman_softc *sc; + struct resource_list *rl; + struct resource_list_entry *rle = NULL; + struct resource *res; + int i, isdefault, passthrough; + + isdefault = RMAN_IS_DEFAULT_RANGE(start, end); + passthrough = (device_get_parent(child) != bus); + sc = device_get_softc(bus); + rl = BUS_GET_RESOURCE_LIST(bus, child); + switch (type) { + case SYS_RES_MEMORY: + KASSERT(!(isdefault && passthrough), + ("%s: passthrough of default allocation", __func__)); + if (!passthrough) { + rle = resource_list_find(rl, type, *rid); + if (rle == NULL) + return (NULL); + KASSERT(rle->res == NULL, + ("%s: resource entry is busy", __func__)); + if (isdefault) { + start = rle->start; + count = ulmax(count, rle->count); + end = ulmax(rle->end, start + count - 1); + } + } + + res = NULL; + /* Map fman ranges to nexus ranges. */ + for (i = 0; i < sc->sc_base.nranges; i++) { + if (start >= sc->sc_base.ranges[i].bus && end < + sc->sc_base.ranges[i].bus + sc->sc_base.ranges[i].size) { + start += rman_get_start(sc->mem_res); + end += rman_get_start(sc->mem_res); + res = rman_reserve_resource(&sc->rman, start, + end, count, flags & ~RF_ACTIVE, child); + if (res == NULL) + return (NULL); + rman_set_rid(res, *rid); + if ((flags & RF_ACTIVE) != 0 && bus_activate_resource( + child, type, *rid, res) != 0) { + rman_release_resource(res); + return (NULL); + } + break; + } + } + if (!passthrough) + rle->res = res; + return (res); + case SYS_RES_IRQ: + return (resource_list_alloc(rl, bus, child, type, rid, start, + end, count, flags)); + } + return (NULL); +} + +static int +fman_fill_ranges(phandle_t node, struct simplebus_softc *sc) +{ + int host_address_cells; + cell_t *base_ranges; + ssize_t nbase_ranges; + int err; + int i, j, k; + + err = OF_searchencprop(OF_parent(node), "#address-cells", + &host_address_cells, sizeof(host_address_cells)); + if (err <= 0) + return (-1); + + nbase_ranges = OF_getproplen(node, "ranges"); + if (nbase_ranges < 0) + return (-1); + sc->nranges = nbase_ranges / sizeof(cell_t) / + (sc->acells + host_address_cells + sc->scells); + if (sc->nranges == 0) + return (0); + + sc->ranges = malloc(sc->nranges * sizeof(sc->ranges[0]), + M_DEVBUF, M_WAITOK); + base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK); + OF_getencprop(node, "ranges", base_ranges, nbase_ranges); + + for (i = 0, j = 0; i < sc->nranges; i++) { + sc->ranges[i].bus = 0; + for (k = 0; k < sc->acells; k++) { + sc->ranges[i].bus <<= 32; + sc->ranges[i].bus |= base_ranges[j++]; + } + sc->ranges[i].host = 0; + for (k = 0; k < host_address_cells; k++) { + sc->ranges[i].host <<= 32; + sc->ranges[i].host |= base_ranges[j++]; + } + sc->ranges[i].size = 0; + for (k = 0; k < sc->scells; k++) { + sc->ranges[i].size <<= 32; + sc->ranges[i].size |= base_ranges[j++]; + } + } + + free(base_ranges, M_DEVBUF); + return (sc->nranges); +} + static t_Handle fman_init(struct fman_softc *sc, struct fman_config *cfg) { - struct ofw_bus_devinfo obd; phandle_t node; t_FmParams fm_params; t_Handle muram_handle, fm_handle; @@ -166,9 +342,11 @@ fman_init(struct fman_softc *sc, struct fman_config *cfg) simplebus_init(sc->sc_base.dev, 0); node = ofw_bus_get_node(sc->sc_base.dev); + fman_fill_ranges(node, &sc->sc_base); + sc->rman.rm_type = RMAN_ARRAY; + sc->rman.rm_descr = "FMan range"; + rman_init_from_resource(&sc->rman, sc->mem_res); for (node = OF_child(node); node > 0; node = OF_peer(node)) { - if (ofw_bus_gen_setup_devinfo(&obd, node) != 0) - continue; simplebus_add_device(sc->sc_base.dev, node, 0, NULL, -1, NULL); } diff --git a/sys/dev/dpaa/fman.h b/sys/dev/dpaa/fman.h index 0e78bf7e95b..9854f7a81f3 100644 --- a/sys/dev/dpaa/fman.h +++ b/sys/dev/dpaa/fman.h @@ -39,6 +39,7 @@ struct fman_softc { struct resource *mem_res; struct resource *irq_res; struct resource *err_irq_res; + struct rman rman; int mem_rid; int irq_rid; int err_irq_rid; @@ -54,6 +55,12 @@ struct fman_softc { * @group QMan bus interface. * @{ */ +struct resource * fman_alloc_resource(device_t bus, device_t child, int type, + int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags); +int fman_activate_resource(device_t bus, device_t child, + int type, int rid, struct resource *res); +int fman_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *res); int fman_attach(device_t dev); int fman_detach(device_t dev); int fman_suspend(device_t dev); diff --git a/sys/dev/dpaa/fman_fdt.c b/sys/dev/dpaa/fman_fdt.c index 95fd619307a..6f7950f308c 100644 --- a/sys/dev/dpaa/fman_fdt.c +++ b/sys/dev/dpaa/fman_fdt.c @@ -56,6 +56,9 @@ static device_method_t fman_methods[] = { DEVMETHOD(device_suspend, fman_suspend), DEVMETHOD(device_resume, fman_resume_dev), + DEVMETHOD(bus_alloc_resource, fman_alloc_resource), + DEVMETHOD(bus_activate_resource, fman_activate_resource), + DEVMETHOD(bus_release_resource, fman_release_resource), { 0, 0 } }; diff --git a/sys/dev/dpaa/if_dtsec.c b/sys/dev/dpaa/if_dtsec.c index 3783212ab52..f2ec5e16f4f 100644 --- a/sys/dev/dpaa/if_dtsec.c +++ b/sys/dev/dpaa/if_dtsec.c @@ -188,7 +188,7 @@ dtsec_fm_mac_init(struct dtsec_softc *sc, uint8_t *mac) memset(¶ms, 0, sizeof(params)); memcpy(¶ms.addr, mac, sizeof(params.addr)); - params.baseAddr = sc->sc_fm_base + sc->sc_mac_mem_offset; + params.baseAddr = rman_get_bushandle(sc->sc_mem); params.enetMode = sc->sc_mac_enet_mode; params.macId = sc->sc_eth_id; params.mdioIrq = sc->sc_mac_mdio_irq; diff --git a/sys/dev/dpaa/if_dtsec.h b/sys/dev/dpaa/if_dtsec.h index 0f9aa341d97..6fa75bd147d 100644 --- a/sys/dev/dpaa/if_dtsec.h +++ b/sys/dev/dpaa/if_dtsec.h @@ -52,6 +52,7 @@ struct dtsec_softc { struct ifnet *sc_ifnet; device_t sc_dev; + struct resource *sc_mem; struct mtx sc_lock; int sc_mode; diff --git a/sys/dev/dpaa/if_dtsec_fdt.c b/sys/dev/dpaa/if_dtsec_fdt.c index b653fbd5f0c..8b55b3ef51c 100644 --- a/sys/dev/dpaa/if_dtsec_fdt.c +++ b/sys/dev/dpaa/if_dtsec_fdt.c @@ -32,8 +32,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include + #include #include @@ -134,6 +137,7 @@ dtsec_fdt_attach(device_t dev) phandle_t fman_rxtx_node[2]; char phy_type[6]; pcell_t fman_tx_cell; + int rid; sc = device_get_softc(dev); enet_node = ofw_bus_get_node(dev); @@ -154,8 +158,9 @@ dtsec_fdt_attach(device_t dev) return(ENXIO); /* Get MAC memory offset in SoC */ - if (OF_getprop(enet_node, "reg", (void *)&sc->sc_mac_mem_offset, - sizeof(sc->sc_mac_mem_offset)) <= 0) + rid = 0; + sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (sc->sc_mem == NULL) return (ENXIO); /* Get PHY address */ diff --git a/sys/dev/dpaa/if_dtsec_rm.c b/sys/dev/dpaa/if_dtsec_rm.c index 61c2f5d87de..e1b6cc77cf0 100644 --- a/sys/dev/dpaa/if_dtsec_rm.c +++ b/sys/dev/dpaa/if_dtsec_rm.c @@ -161,7 +161,7 @@ dtsec_rm_fm_port_rx_init(struct dtsec_softc *sc, int unit) params.h_Fm = sc->sc_fmh; params.portType = dtsec_fm_port_rx_type(sc->sc_eth_dev_type); params.portId = sc->sc_eth_id; - params.independentModeEnable = FALSE; + params.independentModeEnable = false; params.liodnBase = FM_PORT_LIODN_BASE; params.f_Exception = dtsec_fm_port_rx_exception_callback; params.h_App = sc; @@ -209,7 +209,7 @@ dtsec_rm_fm_port_tx_init(struct dtsec_softc *sc, int unit) params.h_Fm = sc->sc_fmh; params.portType = dtsec_fm_port_tx_type(sc->sc_eth_dev_type); params.portId = sc->sc_eth_id; - params.independentModeEnable = FALSE; + params.independentModeEnable = false; params.liodnBase = FM_PORT_LIODN_BASE; params.f_Exception = dtsec_fm_port_tx_exception_callback; params.h_App = sc; @@ -458,7 +458,7 @@ dtsec_rm_fqr_rx_init(struct dtsec_softc *sc) /* Default Frame Queue */ fqr = qman_fqr_create(1, DTSEC_RM_FQR_RX_CHANNEL, DTSEC_RM_FQR_RX_WQ, - FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0, 0); + false, 0, false, false, true, false, 0, 0, 0); if (fqr == NULL) { device_printf(sc->sc_dev, "could not create default RX queue" "\n"); @@ -497,7 +497,7 @@ dtsec_rm_fqr_tx_init(struct dtsec_softc *sc) /* TX Frame Queue */ fqr = qman_fqr_create(1, sc->sc_port_tx_qman_chan, - DTSEC_RM_FQR_TX_WQ, FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0, 0); + DTSEC_RM_FQR_TX_WQ, false, 0, false, false, true, false, 0, 0, 0); if (fqr == NULL) { device_printf(sc->sc_dev, "could not create default TX queue" "\n"); @@ -508,7 +508,7 @@ dtsec_rm_fqr_tx_init(struct dtsec_softc *sc) /* TX Confirmation Frame Queue */ fqr = qman_fqr_create(1, DTSEC_RM_FQR_TX_CONF_CHANNEL, - DTSEC_RM_FQR_TX_CONF_WQ, FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0, + DTSEC_RM_FQR_TX_CONF_WQ, false, 0, false, false, true, false, 0, 0, 0); if (fqr == NULL) { device_printf(sc->sc_dev, "could not create TX confirmation " diff --git a/sys/powerpc/conf/QORIQ64 b/sys/powerpc/conf/QORIQ64 index b834377f3cc..1fbc69479d4 100644 --- a/sys/powerpc/conf/QORIQ64 +++ b/sys/powerpc/conf/QORIQ64 @@ -11,6 +11,7 @@ ident MPC85XX machine powerpc powerpc64 +include "dpaa/config.dpaa" makeoptions DEBUG="-Wa,-me500 -g" makeoptions WERROR="-Werror -Wno-format -Wno-redundant-decls" makeoptions NO_MODULES=yes @@ -73,6 +74,7 @@ device da device ds1553 device em device alc +device dpaa device ether device fxp device gpio