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:
parent
337698b78d
commit
a32b54357f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=325204
@ -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*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 "
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user