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.
This commit is contained in:
Justin Hibbits 2017-10-31 02:53:50 +00:00
parent 337698b78d
commit a32b54357f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=325204
11 changed files with 213 additions and 17 deletions

View File

@ -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*/

View File

@ -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);
}

View File

@ -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);

View File

@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
#include "opt_platform.h"
#include <contrib/ncsw/inc/Peripherals/fm_ext.h>
@ -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);
}

View File

@ -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);

View File

@ -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 }
};

View File

@ -188,7 +188,7 @@ dtsec_fm_mac_init(struct dtsec_softc *sc, uint8_t *mac)
memset(&params, 0, sizeof(params));
memcpy(&params.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;

View File

@ -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;

View File

@ -32,8 +32,11 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/socket.h>
#include <machine/bus.h>
#include <powerpc/mpc85xx/mpc85xx.h>
#include <net/if.h>
@ -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 */

View File

@ -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 "

View File

@ -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