Fix xae(4) driver attachement on the Government Furnished Equipment (GFE)
riscv cores. GFE cores come with standard DTS file that lacks standard 'dmas =' property, which means xae(4) could not find a DMA controller to use. The 'dmas' property could not be added to the DTS file because the ethernet controller and DMA engine parts in Linux are implemented in a single driver. Instead of 'dmas' property the standard Xilinx 'axistream-connected' property is provided, so fallback to use it instead. Suggested by: James Clarke <jrtc27@jrtc27.com> Reviewed by: James Clarke <jrtc27@jrtc27.com> Sponsored by: DARPA, AFRL
This commit is contained in:
parent
79208b1025
commit
a8692c16c9
@ -510,6 +510,24 @@ xdma_ofw_get(device_t dev, const char *prop)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate xdma controller.
|
||||
*/
|
||||
xdma_controller_t *
|
||||
xdma_get(device_t dev, device_t dma_dev)
|
||||
{
|
||||
xdma_controller_t *xdma;
|
||||
|
||||
xdma = malloc(sizeof(struct xdma_controller),
|
||||
M_XDMA, M_WAITOK | M_ZERO);
|
||||
xdma->dev = dev;
|
||||
xdma->dma_dev = dma_dev;
|
||||
|
||||
TAILQ_INIT(&xdma->channels);
|
||||
|
||||
return (xdma);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free xDMA controller object.
|
||||
*/
|
||||
|
@ -231,6 +231,7 @@ static MALLOC_DEFINE(M_XDMA, "xdma", "xDMA framework");
|
||||
|
||||
/* xDMA controller ops */
|
||||
xdma_controller_t *xdma_ofw_get(device_t dev, const char *prop);
|
||||
xdma_controller_t *xdma_get(device_t dev, device_t dma_dev);
|
||||
int xdma_put(xdma_controller_t *xdma);
|
||||
vmem_t * xdma_get_memory(device_t dev);
|
||||
void xdma_put_memory(vmem_t *vmem);
|
||||
|
@ -61,6 +61,15 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "xdma_if.h"
|
||||
|
||||
#define READ4(_sc, _reg) \
|
||||
bus_space_read_4(_sc->bst, _sc->bsh, _reg)
|
||||
#define WRITE4(_sc, _reg, _val) \
|
||||
bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
|
||||
#define READ8(_sc, _reg) \
|
||||
bus_space_read_8(_sc->bst, _sc->bsh, _reg)
|
||||
#define WRITE8(_sc, _reg, _val) \
|
||||
bus_space_write_8(_sc->bst, _sc->bsh, _reg, _val)
|
||||
|
||||
#define AXIDMA_DEBUG
|
||||
#undef AXIDMA_DEBUG
|
||||
|
||||
@ -70,17 +79,8 @@ __FBSDID("$FreeBSD$");
|
||||
#define dprintf(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define AXIDMA_NCHANNELS 2
|
||||
#define AXIDMA_DESCS_NUM 512
|
||||
#define AXIDMA_TX_CHAN 0
|
||||
#define AXIDMA_RX_CHAN 1
|
||||
|
||||
extern struct bus_space memmap_bus;
|
||||
|
||||
struct axidma_fdt_data {
|
||||
int id;
|
||||
};
|
||||
|
||||
struct axidma_channel {
|
||||
struct axidma_softc *sc;
|
||||
xdma_channel_t *xchan;
|
||||
|
@ -60,14 +60,10 @@
|
||||
#define AXI_TAILDESC_MSB(n) (0x14 + 0x30 * (n)) /* Tail Descriptor Pointer. Upper 32 bits of address. */
|
||||
#define AXI_SG_CTL 0x2C /* Scatter/Gather User and Cache */
|
||||
|
||||
#define READ4(_sc, _reg) \
|
||||
bus_space_read_4(_sc->bst, _sc->bsh, _reg)
|
||||
#define WRITE4(_sc, _reg, _val) \
|
||||
bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
|
||||
#define READ8(_sc, _reg) \
|
||||
bus_space_read_8(_sc->bst, _sc->bsh, _reg)
|
||||
#define WRITE8(_sc, _reg, _val) \
|
||||
bus_space_write_8(_sc->bst, _sc->bsh, _reg, _val)
|
||||
#define AXIDMA_NCHANNELS 2
|
||||
#define AXIDMA_DESCS_NUM 512
|
||||
#define AXIDMA_TX_CHAN 0
|
||||
#define AXIDMA_RX_CHAN 1
|
||||
|
||||
struct axidma_desc {
|
||||
uint32_t next;
|
||||
@ -93,4 +89,8 @@ struct axidma_desc {
|
||||
uint32_t reserved[3];
|
||||
};
|
||||
|
||||
struct axidma_fdt_data {
|
||||
int id;
|
||||
};
|
||||
|
||||
#endif /* !_DEV_XILINX_AXIDMA_H_ */
|
||||
|
@ -64,6 +64,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/xilinx/if_xaereg.h>
|
||||
#include <dev/xilinx/if_xaevar.h>
|
||||
|
||||
#include <dev/xilinx/axidma.h>
|
||||
|
||||
#include "miibus_if.h"
|
||||
|
||||
#define READ4(_sc, _reg) \
|
||||
@ -774,6 +776,68 @@ xae_phy_fixup(struct xae_softc *sc)
|
||||
} while ((PHY1_RD(sc, MII_BMSR) & BMSR_ACOMP) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
get_xdma_std(struct xae_softc *sc)
|
||||
{
|
||||
|
||||
sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
|
||||
if (sc->xdma_tx == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
sc->xdma_rx = xdma_ofw_get(sc->dev, "rx");
|
||||
if (sc->xdma_rx == NULL) {
|
||||
xdma_put(sc->xdma_tx);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
get_xdma_axistream(struct xae_softc *sc)
|
||||
{
|
||||
struct axidma_fdt_data *data;
|
||||
device_t dma_dev;
|
||||
phandle_t node;
|
||||
pcell_t prop;
|
||||
size_t len;
|
||||
|
||||
node = ofw_bus_get_node(sc->dev);
|
||||
len = OF_getencprop(node, "axistream-connected", &prop, sizeof(prop));
|
||||
if (len != sizeof(prop)) {
|
||||
device_printf(sc->dev,
|
||||
"%s: Couldn't get axistream-connected prop.\n", __func__);
|
||||
return (ENXIO);
|
||||
}
|
||||
dma_dev = OF_device_from_xref(prop);
|
||||
if (dma_dev == NULL) {
|
||||
device_printf(sc->dev, "Could not get DMA device by xref.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
sc->xdma_tx = xdma_get(sc->dev, dma_dev);
|
||||
if (sc->xdma_tx == NULL) {
|
||||
device_printf(sc->dev, "Could not find DMA controller.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
data = malloc(sizeof(struct axidma_fdt_data),
|
||||
M_DEVBUF, (M_WAITOK | M_ZERO));
|
||||
data->id = AXIDMA_TX_CHAN;
|
||||
sc->xdma_tx->data = data;
|
||||
|
||||
sc->xdma_rx = xdma_get(sc->dev, dma_dev);
|
||||
if (sc->xdma_rx == NULL) {
|
||||
device_printf(sc->dev, "Could not find DMA controller.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
data = malloc(sizeof(struct axidma_fdt_data),
|
||||
M_DEVBUF, (M_WAITOK | M_ZERO));
|
||||
data->id = AXIDMA_RX_CHAN;
|
||||
sc->xdma_rx->data = data;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
setup_xdma(struct xae_softc *sc)
|
||||
{
|
||||
@ -784,15 +848,16 @@ setup_xdma(struct xae_softc *sc)
|
||||
dev = sc->dev;
|
||||
|
||||
/* Get xDMA controller */
|
||||
sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
|
||||
if (sc->xdma_tx == NULL) {
|
||||
device_printf(dev, "Could not find DMA controller.\n");
|
||||
return (ENXIO);
|
||||
error = get_xdma_std(sc);
|
||||
|
||||
if (error) {
|
||||
device_printf(sc->dev,
|
||||
"Fallback to axistream-connected property\n");
|
||||
error = get_xdma_axistream(sc);
|
||||
}
|
||||
|
||||
sc->xdma_rx = xdma_ofw_get(sc->dev, "rx");
|
||||
if (sc->xdma_rx == NULL) {
|
||||
device_printf(dev, "Could not find DMA controller.\n");
|
||||
if (error) {
|
||||
device_printf(dev, "Could not find xDMA controllers.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user