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
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=357653
@ -510,6 +510,24 @@ xdma_ofw_get(device_t dev, const char *prop)
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
* Free xDMA controller object.
|
||||||
*/
|
*/
|
||||||
|
@ -231,6 +231,7 @@ static MALLOC_DEFINE(M_XDMA, "xdma", "xDMA framework");
|
|||||||
|
|
||||||
/* xDMA controller ops */
|
/* xDMA controller ops */
|
||||||
xdma_controller_t *xdma_ofw_get(device_t dev, const char *prop);
|
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);
|
int xdma_put(xdma_controller_t *xdma);
|
||||||
vmem_t * xdma_get_memory(device_t dev);
|
vmem_t * xdma_get_memory(device_t dev);
|
||||||
void xdma_put_memory(vmem_t *vmem);
|
void xdma_put_memory(vmem_t *vmem);
|
||||||
|
@ -61,6 +61,15 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "xdma_if.h"
|
#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
|
#define AXIDMA_DEBUG
|
||||||
#undef AXIDMA_DEBUG
|
#undef AXIDMA_DEBUG
|
||||||
|
|
||||||
@ -70,17 +79,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define dprintf(fmt, ...)
|
#define dprintf(fmt, ...)
|
||||||
#endif
|
#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;
|
extern struct bus_space memmap_bus;
|
||||||
|
|
||||||
struct axidma_fdt_data {
|
|
||||||
int id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct axidma_channel {
|
struct axidma_channel {
|
||||||
struct axidma_softc *sc;
|
struct axidma_softc *sc;
|
||||||
xdma_channel_t *xchan;
|
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_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 AXI_SG_CTL 0x2C /* Scatter/Gather User and Cache */
|
||||||
|
|
||||||
#define READ4(_sc, _reg) \
|
#define AXIDMA_NCHANNELS 2
|
||||||
bus_space_read_4(_sc->bst, _sc->bsh, _reg)
|
#define AXIDMA_DESCS_NUM 512
|
||||||
#define WRITE4(_sc, _reg, _val) \
|
#define AXIDMA_TX_CHAN 0
|
||||||
bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
|
#define AXIDMA_RX_CHAN 1
|
||||||
#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)
|
|
||||||
|
|
||||||
struct axidma_desc {
|
struct axidma_desc {
|
||||||
uint32_t next;
|
uint32_t next;
|
||||||
@ -93,4 +89,8 @@ struct axidma_desc {
|
|||||||
uint32_t reserved[3];
|
uint32_t reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct axidma_fdt_data {
|
||||||
|
int id;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* !_DEV_XILINX_AXIDMA_H_ */
|
#endif /* !_DEV_XILINX_AXIDMA_H_ */
|
||||||
|
@ -64,6 +64,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/xilinx/if_xaereg.h>
|
#include <dev/xilinx/if_xaereg.h>
|
||||||
#include <dev/xilinx/if_xaevar.h>
|
#include <dev/xilinx/if_xaevar.h>
|
||||||
|
|
||||||
|
#include <dev/xilinx/axidma.h>
|
||||||
|
|
||||||
#include "miibus_if.h"
|
#include "miibus_if.h"
|
||||||
|
|
||||||
#define READ4(_sc, _reg) \
|
#define READ4(_sc, _reg) \
|
||||||
@ -774,6 +776,68 @@ xae_phy_fixup(struct xae_softc *sc)
|
|||||||
} while ((PHY1_RD(sc, MII_BMSR) & BMSR_ACOMP) == 0);
|
} 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
|
static int
|
||||||
setup_xdma(struct xae_softc *sc)
|
setup_xdma(struct xae_softc *sc)
|
||||||
{
|
{
|
||||||
@ -784,15 +848,16 @@ setup_xdma(struct xae_softc *sc)
|
|||||||
dev = sc->dev;
|
dev = sc->dev;
|
||||||
|
|
||||||
/* Get xDMA controller */
|
/* Get xDMA controller */
|
||||||
sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
|
error = get_xdma_std(sc);
|
||||||
if (sc->xdma_tx == NULL) {
|
|
||||||
device_printf(dev, "Could not find DMA controller.\n");
|
if (error) {
|
||||||
return (ENXIO);
|
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 (error) {
|
||||||
if (sc->xdma_rx == NULL) {
|
device_printf(dev, "Could not find xDMA controllers.\n");
|
||||||
device_printf(dev, "Could not find DMA controller.\n");
|
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user